11name : Upload dev build from PR
22
3+ # See https://github.com/plotly/plotly.js/blob/master/CONTRIBUTING.md#live-links-to-dev-builds
4+ # for documentation on the usage of this workflow.
5+
36on :
47 workflow_run :
58 workflows : ["Publish Dist"] # publish-dist.yml
912 inputs :
1013 pr_number :
1114 description : ' PR Number to deploy'
12- required : true
13- run_id :
14- description : ' The Run ID of the CI workflow that has the artifact'
15- required : true
15+ required : false
16+
17+ env :
18+ ARTIFACT_UPLOAD_WORKFLOW_NAME : " Publish Dist"
19+ UPLOAD_DIR_NAME : " upload"
1620
1721jobs :
1822 upload :
1923 runs-on : ubuntu-latest
24+ # Only run on manual dispatch,
25+ # OR if the parent run succeeded and was triggered by a PR from
26+ # a branch in the main repo (not a fork)
2027 if : |
2128 github.event_name == 'workflow_dispatch' ||
2229 (
2330 github.event_name == 'workflow_run' &&
2431 github.event.workflow_run.event == 'pull_request' &&
25- github.event.workflow_run.conclusion == 'success'
32+ github.event.workflow_run.conclusion == 'success' &&
33+ github.event.workflow_run.head_repository.full_name == github.repository
2634 )
2735 steps :
36+ - name : Get required metadata (PR number, commit SHA, workflow run ID containing artifacts)
37+ id : get-metadata
38+ env :
39+ GH_TOKEN : ${{ github.token }}
40+ GH_EVENT_NAME : ${{ github.event_name }}
41+ GH_REPO : ${{ github.repository }}
42+ SHA : ${{ github.event.workflow_run.sha }}
43+ RUN_ID : ${{ github.event.workflow_run.id }}
44+ PR_NUM : ${{ github.event.workflow_run.pull_requests[0].number || inputs.pr_number }}
45+ run : |
46+ # Get SHA from manually-provided PR number if triggered by workflow_dispatch
47+ if [ "${GH_EVENT_NAME}" == "workflow_dispatch" ]; then
48+ if [ -n "${PR_NUM}" ]; then
49+ SHA=$(gh pr view "${PR_NUM}" --repo "${GH_REPO}" --json headRefOid --template '{{.headRefOid}}')
50+ fi
51+ fi
52+
53+ # At this point, SHA should be defined. If not, fail the workflow
54+ if [ -z "${SHA}" ]; then
55+ echo "Failed to get commit SHA, exiting"
56+ exit 1
57+ fi
58+
59+ # If PR_NUM is empty, get PR number using SHA
60+ if [ -z "${PR_NUM}" ]; then
61+ PR_NUM=$(gh pr list --search "sha:${SHA}" --state open --json number --jq '.[0].number')
62+ fi
63+
64+ # Validate that we have a valid PR number
65+ if [ -z "${PR_NUM}" ] || [[ ! "${PR_NUM}" =~ ^[1-9][0-9]{0,4}$ ]]; then
66+ echo "Failed to get PR number, exiting (PR_NUM=${PR_NUM})"
67+ exit 1
68+ fi
69+
70+ # If RUN_ID is empty, use the gh CLI to get the most recent run ID for SHA
71+ if [ -z "${RUN_ID}" ]; then
72+ RUN_ID=$(gh run list \
73+ --workflow "${ARTIFACT_UPLOAD_WORKFLOW_NAME}" \
74+ --commit "${SHA}" \
75+ --limit 1 \
76+ --json databaseId \
77+ --jq '.[0].databaseId')
78+ fi
79+
80+ # At this point, RUN_ID should be defined. If not, fail the workflow
81+ if [ -z "${RUN_ID}" ]; then
82+ echo "Failed to get workflow run ID, exiting"
83+ exit 1
84+ fi
85+
86+ # Save PR number, commit SHA, short SHA, and run ID to output
87+ echo "PR_NUM=${PR_NUM}" >> $GITHUB_OUTPUT
88+ echo "SHA=${SHA}" >> $GITHUB_OUTPUT
89+ echo "SHORT_SHA=${SHA:0:7}" >> $GITHUB_OUTPUT
90+ echo "RUN_ID=${RUN_ID}" >> $GITHUB_OUTPUT
91+
2892 - name : Download build artifact
2993 id : download-artifact
3094 uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
3195 with :
3296 name : dist # uploaded by publish-dist.yml > publish-dist
33- run-id : ${{ github.event.workflow_run.id || inputs.run_id }}
97+ run-id : ${{ steps.get-metadata.outputs.RUN_ID }}
3498 github-token : ${{ secrets.GITHUB_TOKEN }}
3599 path : temp-dist
36100
37- - name : Setup metadata and prepare folders
101+ - name : Prepare folders
38102 id : setup-metadata
39103 env :
40104 GH_TOKEN : ${{ github.token }}
41- PR_NUM : ${{ github.event.workflow_run.pull_requests[0].number || inputs.pr_number }}
105+ PR_NUM : ${{ steps.get-metadata.outputs.PR_NUM }}
106+ SHA : ${{ steps.get-metadata.outputs.SHA }}
107+ SHORT_SHA : ${{ steps.get-metadata.outputs.SHORT_SHA }}
42108 run : |
43- # Get SHA from triggering workflow, or from manual input
44- if [ "${{ github.event_name }}" == "workflow_run" ]; then
45- SHA="${{ github.event.workflow_run.head_sha }}"
46- else
47- echo "Fetching latest SHA for PR #$PR_NUM..."
48- SHA=$(gh pr view "$PR_NUM" --repo ${{ github.repository }} --json headRefOid --template '{{.headRefOid}}')
49- fi
50- SHORT_SHA=${SHA::7}
51- UPLOAD_DIR_NAME="upload"
52-
53- echo "Using SHA: ${SHA}"
109+ echo "SHA: ${SHA}"
54110 echo "Short SHA: ${SHORT_SHA}"
111+ echo "PR number: ${PR_NUM}"
55112 mkdir -p "${UPLOAD_DIR_NAME}/pr-${PR_NUM}/latest"
56113 mkdir -p "${UPLOAD_DIR_NAME}/pr-${PR_NUM}/${SHORT_SHA}"
57114 # Copy all 3 artifacts (plotly.js, plotly.min.js, plot-schema.json) to /latest/
@@ -65,10 +122,6 @@ jobs:
65122 echo "Created directory ${UPLOAD_DIR_FULL_PATH} with the following contents:"
66123 echo "$(ls -lR ${UPLOAD_DIR_FULL_PATH})"
67124
68- echo "PR_NUM=${PR_NUM}" >> $GITHUB_OUTPUT
69- echo "SHA=${SHA}" >> $GITHUB_OUTPUT
70- echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_OUTPUT
71-
72125 - name : Generate GitHub App token
73126 id : generate-token
74127 uses : actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
@@ -87,32 +140,45 @@ jobs:
87140
88141 - name : Commit and push files
89142 id : commit-and-push
143+ env :
144+ PR_NUM : ${{ steps.get-metadata.outputs.PR_NUM }}
145+ SHORT_SHA : ${{ steps.get-metadata.outputs.SHORT_SHA }}
90146 run : |
91- # 1. Move 'upload' directory into repo folder and cd into repo root
92- mkdir -p plotly.js-dev-builds/upload/
93- cp -r upload/ plotly.js-dev-builds/
147+ # Move 'pr-NNNN/' directory into upload directory inside repo and cd into repo root
148+ TARGET_DIR="${UPLOAD_DIR_NAME}/pr-${PR_NUM}"
149+ mkdir -p "plotly.js-dev-builds/${UPLOAD_DIR_NAME}"
150+ cp -r "${TARGET_DIR}" "plotly.js-dev-builds/${UPLOAD_DIR_NAME}"
94151 cd plotly.js-dev-builds
95152
96- # 2. Configure git
153+ # Configure git
97154 git config user.name "plotly.js-pr-upload"
98155 git config user.email "<>"
99156
100- # 3. add, commit, and push
101- git add upload/
157+ # Add files
158+ git add "${TARGET_DIR}/"
159+
160+ # Ensure that only files in upload/pr-NNNN/ are staged
161+ if git diff --name-only --cached | grep -qv "^${TARGET_DIR}/"; then
162+ echo "Error: Changes detected outside ${TARGET_DIR}/"
163+ exit 1
164+ fi
102165
103166 # Only commit if there are changes
104167 if git diff --staged --quiet; then
105168 echo "No changes to commit"
106169 else
107- git commit -m "Deploy build for PR #${{ steps.setup-metadata.outputs. PR_NUM }} (commit ${{ steps.setup-metadata.outputs. SHORT_SHA } })"
170+ git commit -m "Deploy build for PR #${PR_NUM} (commit ${SHORT_SHA})"
108171 git push origin main
109172 fi
110173
111174 - name : Generate summary
175+ env :
176+ PR_NUM : ${{ steps.get-metadata.outputs.PR_NUM }}
177+ SHORT_SHA : ${{ steps.get-metadata.outputs.SHORT_SHA }}
112178 run : |
113- BASE ="https://plotly.github.io/plotly.js-dev-builds/upload /pr-${{ steps.setup-metadata.outputs. PR_NUM } }"
179+ BASE_URL ="https://plotly.github.io/plotly.js-dev-builds/${UPLOAD_DIR_NAME} /pr-${PR_NUM}"
114180 echo "### PR Build Uploaded" >> $GITHUB_STEP_SUMMARY
115- echo "Builds for PR #${{ steps.setup-metadata.outputs. PR_NUM } } can be accessed at:" >> $GITHUB_STEP_SUMMARY
116- echo "- Latest build for this PR: [$BASE /latest/plotly.min.js]($BASE /latest/plotly.min.js)" >> $GITHUB_STEP_SUMMARY
117- echo "- Build for this commit: [$BASE /${{ steps.setup-metadata.outputs.SHA }} /plotly.min.js]($BASE /${{ steps.setup-metadata.outputs.SHA } }/plotly.min.js)" >> $GITHUB_STEP_SUMMARY
181+ echo "Builds for PR #${PR_NUM} can be accessed at:" >> $GITHUB_STEP_SUMMARY
182+ echo "- Latest build for this PR: [${BASE_URL} /latest/plotly.min.js](${BASE_URL} /latest/plotly.min.js)" >> $GITHUB_STEP_SUMMARY
183+ echo "- Build for this commit: [${BASE_URL} /${SHORT_SHA} /plotly.min.js](${BASE_URL} /${SHORT_SHA }/plotly.min.js)" >> $GITHUB_STEP_SUMMARY
118184 echo "The above links should start working a minute or two after this job completes." >> $GITHUB_STEP_SUMMARY
0 commit comments