Skip to content

Commit a910201

Browse files
committed
ci: Add status update for upload-dev-build
1 parent a677f28 commit a910201

1 file changed

Lines changed: 102 additions & 6 deletions

File tree

.github/workflows/upload-dev-build.yml

Lines changed: 102 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,37 @@ env:
2121
jobs:
2222
upload:
2323
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)
24+
permissions:
25+
checks: write
26+
# Only run on manual dispatch,
27+
# OR if the parent run succeeded and was triggered by a PR.
28+
# Fork PRs run through so we can post a "skipped" commit status to the PR
29+
# head and log why; the actual upload steps are guarded by fork-check so no
30+
# dev build is published for fork PRs (they lack DEV_DEPLOY_APP access).
2731
if: |
2832
github.event_name == 'workflow_dispatch' ||
2933
(
30-
github.event_name == 'workflow_run' &&
34+
github.event_name == 'workflow_run' &&
3135
github.event.workflow_run.event == 'pull_request' &&
32-
github.event.workflow_run.conclusion == 'success' &&
33-
github.event.workflow_run.head_repository.full_name == github.repository
36+
github.event.workflow_run.conclusion == 'success'
3437
)
3538
steps:
39+
- name: Check if PR is from a fork
40+
id: fork-check
41+
env:
42+
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
43+
REPO: ${{ github.repository }}
44+
run: |
45+
if [ -n "${HEAD_REPO}" ] && [ "${HEAD_REPO}" != "${REPO}" ]; then
46+
echo "::notice::Dev-build upload skipped: PR is from a fork (${HEAD_REPO}). Dev builds are only uploaded for PRs from branches within ${REPO}. A maintainer can trigger a build manually via workflow_dispatch with the PR number as input."
47+
echo "is_fork=true" >> "$GITHUB_OUTPUT"
48+
else
49+
echo "is_fork=false" >> "$GITHUB_OUTPUT"
50+
fi
51+
3652
- name: Get required metadata (PR number, commit SHA, workflow run ID containing artifacts)
3753
id: get-metadata
54+
if: steps.fork-check.outputs.is_fork != 'true'
3855
env:
3956
GH_TOKEN: ${{ github.token }}
4057
GH_EVENT_NAME: ${{ github.event_name }}
@@ -91,6 +108,7 @@ jobs:
91108
92109
- name: Download build artifact
93110
id: download-artifact
111+
if: steps.fork-check.outputs.is_fork != 'true'
94112
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
95113
with:
96114
name: dist # uploaded by publish-dist.yml > publish-dist
@@ -100,6 +118,7 @@ jobs:
100118

101119
- name: Prepare folders
102120
id: setup-metadata
121+
if: steps.fork-check.outputs.is_fork != 'true'
103122
env:
104123
GH_TOKEN: ${{ github.token }}
105124
PR_NUM: ${{ steps.get-metadata.outputs.PR_NUM }}
@@ -124,6 +143,7 @@ jobs:
124143
125144
- name: Generate GitHub App token
126145
id: generate-token
146+
if: steps.fork-check.outputs.is_fork != 'true'
127147
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 #v3.1.1
128148
with:
129149
client-id: ${{ vars.DEV_DEPLOY_APP_ID }}
@@ -132,6 +152,7 @@ jobs:
132152
repositories: plotly.js-dev-builds
133153

134154
- name: Check out plotly.js-dev-builds repo
155+
if: steps.fork-check.outputs.is_fork != 'true'
135156
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
136157
with:
137158
repository: plotly/plotly.js-dev-builds
@@ -140,6 +161,7 @@ jobs:
140161

141162
- name: Commit and push files
142163
id: commit-and-push
164+
if: steps.fork-check.outputs.is_fork != 'true'
143165
env:
144166
PR_NUM: ${{ steps.get-metadata.outputs.PR_NUM }}
145167
SHORT_SHA: ${{ steps.get-metadata.outputs.SHORT_SHA }}
@@ -172,6 +194,7 @@ jobs:
172194
fi
173195
174196
- name: Generate summary
197+
if: steps.fork-check.outputs.is_fork != 'true'
175198
env:
176199
PR_NUM: ${{ steps.get-metadata.outputs.PR_NUM }}
177200
SHORT_SHA: ${{ steps.get-metadata.outputs.SHORT_SHA }}
@@ -182,3 +205,76 @@ jobs:
182205
echo "- Latest build for this PR: [${BASE_URL}/latest/plotly.min.js](${BASE_URL}/latest/plotly.min.js)" >> $GITHUB_STEP_SUMMARY
183206
echo "- Build for this commit: [${BASE_URL}/${SHORT_SHA}/plotly.min.js](${BASE_URL}/${SHORT_SHA}/plotly.min.js)" >> $GITHUB_STEP_SUMMARY
184207
echo "The above links should start working a minute or two after this job completes." >> $GITHUB_STEP_SUMMARY
208+
209+
- name: Report dev-build outcome to PR head
210+
# Reach this step for any run that resolved a PR head SHA — both
211+
# workflow_run (auto-triggered by Publish Dist) and workflow_dispatch
212+
# (a maintainer manually dispatching a build). The step then either
213+
# creates a "dev build" check-run on the PR head, or PATCHes the
214+
# existing one so the row updates in place instead of stacking.
215+
if: |
216+
always() && (
217+
(github.event_name == 'workflow_run' && github.event.workflow_run.head_sha != '') ||
218+
(github.event_name == 'workflow_dispatch' && steps.get-metadata.outputs.SHA != '')
219+
)
220+
env:
221+
GH_TOKEN: ${{ github.token }}
222+
REPO: ${{ github.repository }}
223+
SHA: ${{ github.event.workflow_run.head_sha || steps.get-metadata.outputs.SHA }}
224+
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
225+
IS_FORK: ${{ steps.fork-check.outputs.is_fork }}
226+
PR_NUM: ${{ steps.get-metadata.outputs.PR_NUM }}
227+
UPLOAD_OUTCOME: ${{ steps.commit-and-push.outcome }}
228+
RUN_ID: ${{ github.run_id }}
229+
run: |
230+
RUN_URL="https://github.com/${REPO}/actions/runs/${RUN_ID}"
231+
232+
if [ "${IS_FORK}" == "true" ]; then
233+
TITLE="Skipped: PR is from a fork"
234+
CONCLUSION="neutral"
235+
SUMMARY=$(cat <<EOF
236+
Dev builds are not automatically published for PRs from forks (\`${HEAD_REPO}\`) as a security policy.
237+
238+
If you need a dev build for this PR, please **contact a maintainer** and ask them to trigger the *Upload dev build from PR* workflow manually via the Actions tab, providing this PR's number as input.
239+
EOF
240+
)
241+
DETAILS_URL="${RUN_URL}"
242+
elif [ "${UPLOAD_OUTCOME}" == "success" ]; then
243+
TITLE="Dev build available"
244+
CONCLUSION="success"
245+
URL="https://plotly.github.io/plotly.js-dev-builds/${UPLOAD_DIR_NAME}/pr-${PR_NUM}/latest/plotly.min.js"
246+
SUMMARY="Latest dev build for PR #${PR_NUM}: [${URL}](${URL})"
247+
DETAILS_URL="${URL}"
248+
else
249+
TITLE="Dev build upload failed"
250+
CONCLUSION="failure"
251+
SUMMARY="Upload workflow failed. See [the run](${RUN_URL}) for details."
252+
DETAILS_URL="${RUN_URL}"
253+
fi
254+
255+
PAYLOAD=$(jq -n \
256+
--arg conclusion "${CONCLUSION}" \
257+
--arg title "${TITLE}" \
258+
--arg summary "${SUMMARY}" \
259+
--arg details_url "${DETAILS_URL}" \
260+
'{
261+
status: "completed",
262+
conclusion: $conclusion,
263+
details_url: $details_url,
264+
output: {title: $title, summary: $summary}
265+
}')
266+
267+
# Look for an existing "dev build" check-run on this SHA so we can
268+
# PATCH it in place — e.g. so an initial "Skipped: fork" row updates
269+
# to "Dev build available" when a maintainer later dispatches a build.
270+
# If multiple exist (shouldn't happen under normal use), PATCH the most
271+
# recent one identified by the highest check-run id.
272+
EXISTING_ID=$(gh api "repos/${REPO}/commits/${SHA}/check-runs" \
273+
--jq '[.check_runs[] | select(.name == "dev build")] | sort_by(.id) | last | .id // empty')
274+
275+
if [ -n "${EXISTING_ID}" ]; then
276+
echo "${PAYLOAD}" | gh api --method PATCH --input - "repos/${REPO}/check-runs/${EXISTING_ID}"
277+
else
278+
echo "${PAYLOAD}" | jq --arg sha "${SHA}" '. + {name: "dev build", head_sha: $sha}' \
279+
| gh api --method POST --input - "repos/${REPO}/check-runs"
280+
fi

0 commit comments

Comments
 (0)