2525 type : string
2626
2727concurrency :
28- group : publish-pr-preview-${{ github.event.pull_request.number || inputs.pr_number }}
28+ group : publish-pr-preview-${{ github.event.pull_request.number || github.run_id }}
2929 cancel-in-progress : false
3030
3131jobs :
32- build :
32+ context :
3333 if : >-
3434 github.event_name == 'workflow_dispatch' ||
35- (( github.event.label.name == 'publish-preview' ||
35+ (github.event.label.name == 'publish-preview' ||
3636 github.event.label.name == 'publish-docker-preview') &&
37- github.event.pull_request.head.repo.full_name == github.repository)
37+ github.event.pull_request.head.repo.full_name == github.repository
38+ runs-on : ubuntu-latest
39+ timeout-minutes : 5
40+ permissions :
41+ contents : read
42+ pull-requests : read
43+ outputs :
44+ pr_number : ${{ steps.context.outputs.pr_number }}
45+ head_sha : ${{ steps.context.outputs.head_sha }}
46+ steps :
47+ - name : Validate pull request context
48+ id : context
49+ uses : actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
50+ env :
51+ DEFAULT_BRANCH : ${{ github.event.repository.default_branch }}
52+ EVENT_PR_NUMBER : ${{ github.event.pull_request.number }}
53+ INPUT_PR_NUMBER : ${{ inputs.pr_number }}
54+ WORKFLOW_REF : ${{ github.ref }}
55+ with :
56+ script : |
57+ const rawPrNumber = context.eventName === 'workflow_dispatch'
58+ ? process.env.INPUT_PR_NUMBER
59+ : process.env.EVENT_PR_NUMBER;
60+ if (!/^[1-9][0-9]*$/.test(rawPrNumber || '')) {
61+ core.setFailed('Pull request number must contain ASCII digits only.');
62+ return;
63+ }
64+
65+ if (context.eventName === 'workflow_dispatch') {
66+ const defaultRef = `refs/heads/${process.env.DEFAULT_BRANCH}`;
67+ if (process.env.WORKFLOW_REF !== defaultRef) {
68+ core.setFailed(`Run manual previews from ${defaultRef}.`);
69+ return;
70+ }
71+ }
72+
73+ const prNumber = Number(rawPrNumber);
74+ if (!Number.isSafeInteger(prNumber)) {
75+ core.setFailed('Pull request number is outside the supported range.');
76+ return;
77+ }
78+ const {data: pullRequest} = await github.rest.pulls.get({
79+ owner: context.repo.owner,
80+ repo: context.repo.repo,
81+ pull_number: prNumber,
82+ });
83+ if (pullRequest.state !== 'open') {
84+ core.setFailed(`Pull request #${prNumber} is not open.`);
85+ return;
86+ }
87+ if (pullRequest.head.repo?.full_name !== `${context.repo.owner}/${context.repo.repo}`) {
88+ core.setFailed('Preview publication is limited to branches in this repository.');
89+ return;
90+ }
91+
92+ core.setOutput('pr_number', String(prNumber));
93+ core.setOutput('head_sha', pullRequest.head.sha);
94+
95+ build :
96+ needs : context
3897 runs-on : ubuntu-latest
3998 timeout-minutes : 10
4099 permissions :
41100 contents : read
42101 outputs :
43102 preview_version : ${{ steps.version.outputs.preview_version }}
44- pr_number : ${{ steps.context.outputs.pr_number }}
45103 steps :
46104 - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
47105 with :
48- ref : ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', inputs.pr_number) }}
106+ ref : ${{ needs.context.outputs.head_sha }}
49107 fetch-depth : 0
50108 persist-credentials : false
51109
@@ -59,13 +117,6 @@ jobs:
59117 - name : Install distribution validator
60118 run : python -m pip install "twine>=4.0.0"
61119
62- - name : Record preview context
63- id : context
64- env :
65- EVENT_PR_NUMBER : ${{ github.event.pull_request.number }}
66- INPUT_PR_NUMBER : ${{ inputs.pr_number }}
67- run : echo "pr_number=${EVENT_PR_NUMBER:-$INPUT_PR_NUMBER}" >> "$GITHUB_OUTPUT"
68-
69120 - name : Inject deterministic preview version
70121 env :
71122 PREVIEW_ID : ${{ github.run_id }}
@@ -110,7 +161,7 @@ jobs:
110161 retention-days : 14
111162
112163 publish-package :
113- needs : build
164+ needs : [context, build]
114165 if : >-
115166 github.event.label.name == 'publish-preview' ||
116167 (github.event_name == 'workflow_dispatch' && inputs.publish_test_pypi)
@@ -128,7 +179,7 @@ jobs:
128179 path : dist
129180
130181 - name : Publish to TestPyPI
131- uses : pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
182+ uses : pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
132183 with :
133184 repository-url : https://test.pypi.org/legacy/
134185 verbose : true
@@ -137,7 +188,7 @@ jobs:
137188 uses : actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
138189 env :
139190 PREVIEW_VERSION : ${{ needs.build.outputs.preview_version }}
140- PR_NUMBER : ${{ needs.build .outputs.pr_number }}
191+ PR_NUMBER : ${{ needs.context .outputs.pr_number }}
141192 with :
142193 script : |
143194 const marker = '<!-- socketsecurity-pr-preview -->';
@@ -176,7 +227,7 @@ jobs:
176227 }
177228
178229 publish-docker :
179- needs : build
230+ needs : [context, build]
180231 if : >-
181232 github.event.label.name == 'publish-docker-preview' ||
182233 (github.event_name == 'workflow_dispatch' && inputs.publish_docker)
@@ -188,7 +239,9 @@ jobs:
188239 steps :
189240 - uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
190241 with :
191- ref : ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', inputs.pr_number) }}
242+ # Keep the Dockerfile and credential-handling action on trusted code.
243+ # The pull request enters this job only through the built wheel.
244+ ref : ${{ github.event.repository.default_branch }}
192245 fetch-depth : 1
193246 persist-credentials : false
194247
@@ -198,29 +251,28 @@ jobs:
198251 name : socketsecurity-preview-${{ github.run_id }}-${{ github.run_attempt }}
199252 path : dist
200253
201- - uses : docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
202-
203- - uses : docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
254+ - name : Set up Docker publishing
255+ uses : ./.github/actions/setup-docker
204256 with :
205- username : ${{ secrets.DOCKERHUB_USERNAME }}
206- password : ${{ secrets.DOCKERHUB_TOKEN }}
257+ enable-qemu : " false"
258+ dockerhub-username : ${{ secrets.DOCKERHUB_USERNAME }}
259+ dockerhub-token : ${{ secrets.DOCKERHUB_TOKEN }}
207260
208261 - name : Build and push Docker preview
209262 uses : docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
210263 with :
211264 file : Dockerfile.preview
212265 push : true
266+ pull : true
213267 platforms : linux/amd64
214- cache-from : type=gha
215- cache-to : type=gha,mode=max
216- tags : socketdev/cli:pr-${{ needs.build.outputs.pr_number }}
268+ tags : socketdev/cli:pr-${{ needs.context.outputs.pr_number }}
217269 build-args : |
218270 SDK_PREVIEW_VERSION=${{ inputs.sdk_preview_version }}
219271
220272 - name : Comment on pull request
221273 uses : actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
222274 env :
223- PR_NUMBER : ${{ needs.build .outputs.pr_number }}
275+ PR_NUMBER : ${{ needs.context .outputs.pr_number }}
224276 with :
225277 script : |
226278 const marker = '<!-- socketsecurity-docker-preview -->';
0 commit comments