-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathaction.yml
More file actions
504 lines (462 loc) · 22.5 KB
/
Copy pathaction.yml
File metadata and controls
504 lines (462 loc) · 22.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
name: 'Deploy to IPFS'
description: 'Merkleize a static site into a CAR file (IPFS DAG). Optionally pin to your own Kubo or IPFS Cluster. Compose with any third-party pinning service via its own action or CLI.'
branding:
icon: 'box'
color: 'blue'
inputs:
kubo-version:
description: 'Kubo version used to merkleize, create CAR file, and pin. A release tag from https://github.com/ipfs/kubo/releases'
default: 'v0.43.1'
required: false
path-to-deploy:
description: 'Path to the directory containing the frontend build to merkleize into a CAR file and deploy to IPFS'
required: true
cid-profile:
description: 'Kubo CID profile applied before merkleizing. Controls default CID version, chunker, raw leaves, and HAMT settings. Valid values: `unixfs-v1-2025` (recommended, follows IPIP-0499) or `unixfs-v0-2015` (legacy 2015 defaults). Pass an empty string to skip applying any profile and rely on Kubo built-in defaults.'
default: 'unixfs-v1-2025'
required: false
ipfs-add-options:
description: 'Extra options to pass to Kubo `ipfs add`. Default is empty so the chosen `cid-profile` governs CID version, chunker, raw-leaves, and link fanout. Override only when you need to deviate from the profile. See https://docs.ipfs.tech/reference/kubo/cli/#ipfs-add.'
default: ''
required: false
kubo-api-url:
description: 'Kubo RPC API URL to pass to `ipfs --api`, e.g. `/dns/YOUR_DOMAIN/tcp/443/https`'
required: false
kubo-api-auth:
description: 'Kubo RPC API auth secret to pass to `ipfs --api-auth`, e.g. `basic:hello:world` (defined as `AuthSecret` in `API.Authorizations` Kubo config)'
required: false
cluster-url:
description: 'IPFS Cluster URL to pass to ipfs-cluster-ctl --host, e.g. /dnsaddr/...'
required: false
cluster-user:
description: 'IPFS Cluster username used for basic http auth'
required: false
cluster-password:
description: 'IPFS Cluster password used for basic http auth'
required: false
cluster-retry-attempts:
description: 'Number of retry attempts for IPFS Cluster uploads. Must be a positive integer.'
default: '3'
required: false
cluster-timeout-minutes:
description: 'Timeout in minutes for each IPFS Cluster upload attempt'
default: '5'
required: false
ipfs-cluster-ctl-version:
description: 'IPFS Cluster CLI version to use. A release tag from https://github.com/ipfs-cluster/ipfs-cluster/releases'
default: 'v1.1.6'
required: false
cluster-pin-expire-in:
description: 'Time duration after which the pin will expire in IPFS Cluster (e.g. 720h for 30 days). Only supported by IPFS Cluster.'
required: false
pin-name:
description: 'Custom name for the IPFS Cluster pin. If unset, defaults to "{repo-name}-{commit-sha-short}"'
required: false
github-token:
description: 'GitHub token for updating commit status and PR comments'
required: true
set-github-status:
description: 'Set GitHub commit status with build CID. Use "true" or "false" (as strings). If unset, the status is set only when a Kubo or IPFS Cluster pin is configured.'
default: ''
required: false
github-status-gw:
description: 'Gateway URL to use for the commit status target_url. Defaults to `inbrowser.link`'
default: 'inbrowser.link'
required: false
set-pr-comment:
description: 'Set PR comments with IPFS deployment information. Use "true" or "false" (as strings). If unset, the comment is posted only when a Kubo or IPFS Cluster pin is configured.'
default: ''
required: false
upload-car-artifact:
description: 'Upload the CAR file as a GitHub artifact'
default: 'true'
required: false
car-file-name:
description: 'Local filename for the produced CAR. Useful when running this action more than once in the same job, or when downstream steps expect a specific filename. Exposed via the `car-path` output.'
default: 'build.car'
required: false
# Removed in v2. Re-declared so a user who upgraded from @v1 without migrating
# gets a clear error instead of a silently dropped pinning step. See ./docs/recipes/.
pinata-jwt-token:
description: '[REMOVED in v2] Native Pinata pinning was removed. See ./docs/recipes/pinata.md'
required: false
pinata-pinning-url:
description: '[REMOVED in v2] Native Pinata pinning was removed. See ./docs/recipes/pinata.md'
required: false
filebase-access-key:
description: '[REMOVED in v2] Native Filebase upload was removed. See ./docs/recipes/filebase.md'
required: false
filebase-secret-key:
description: '[REMOVED in v2] Native Filebase upload was removed. See ./docs/recipes/filebase.md'
required: false
filebase-bucket:
description: '[REMOVED in v2] Native Filebase upload was removed. See ./docs/recipes/filebase.md'
required: false
storacha-key:
description: '[REMOVED in v2] Storacha service was sunset on 2026-04-15. Pick another service from ./docs/recipes/'
required: false
storacha-proof:
description: '[REMOVED in v2] Storacha service was sunset on 2026-04-15. Pick another service from ./docs/recipes/'
required: false
outputs:
cid:
description: 'Root CID of the produced CAR'
value: ${{ steps.merkleize.outputs.cid }}
car-path:
description: 'Workspace-relative path to the produced CAR file. Follow-up steps can read it directly without assuming the filename.'
value: ${{ steps.merkleize.outputs.car-path }}
car-artifact-name:
description: 'Name under which the CAR was uploaded as a GitHub workflow artifact. Empty when `upload-car-artifact` is `false`.'
value: ${{ steps.car-artifact.outputs.name }}
runs:
using: 'composite'
steps:
- name: Detect v1 inputs (removed in v2)
shell: bash
# Env vars are prefixed with INPUT_ so they can't collide with user-defined
# secrets that often share these names (PINATA_JWT_TOKEN, FILEBASE_*, etc).
env:
INPUT_PINATA_JWT_TOKEN: ${{ inputs.pinata-jwt-token }}
INPUT_PINATA_PINNING_URL: ${{ inputs.pinata-pinning-url }}
INPUT_FILEBASE_ACCESS_KEY: ${{ inputs.filebase-access-key }}
INPUT_FILEBASE_SECRET_KEY: ${{ inputs.filebase-secret-key }}
INPUT_FILEBASE_BUCKET: ${{ inputs.filebase-bucket }}
INPUT_STORACHA_KEY: ${{ inputs.storacha-key }}
INPUT_STORACHA_PROOF: ${{ inputs.storacha-proof }}
run: |
REMOVED=()
[ -n "$INPUT_PINATA_JWT_TOKEN" ] && REMOVED+=("pinata-jwt-token")
[ -n "$INPUT_PINATA_PINNING_URL" ] && REMOVED+=("pinata-pinning-url")
[ -n "$INPUT_FILEBASE_ACCESS_KEY" ] && REMOVED+=("filebase-access-key")
[ -n "$INPUT_FILEBASE_SECRET_KEY" ] && REMOVED+=("filebase-secret-key")
[ -n "$INPUT_FILEBASE_BUCKET" ] && REMOVED+=("filebase-bucket")
[ -n "$INPUT_STORACHA_KEY" ] && REMOVED+=("storacha-key")
[ -n "$INPUT_STORACHA_PROOF" ] && REMOVED+=("storacha-proof")
if [ ${#REMOVED[@]} -eq 0 ]; then
exit 0
fi
# Build per-input migration pointers
declare -A POINTERS=(
[pinata-jwt-token]="https://github.com/ipshipyard/ipfs-deploy-action/blob/main/docs/recipes/pinata.md"
[pinata-pinning-url]="https://github.com/ipshipyard/ipfs-deploy-action/blob/main/docs/recipes/pinata.md"
[filebase-access-key]="https://github.com/ipshipyard/ipfs-deploy-action/blob/main/docs/recipes/filebase.md"
[filebase-secret-key]="https://github.com/ipshipyard/ipfs-deploy-action/blob/main/docs/recipes/filebase.md"
[filebase-bucket]="https://github.com/ipshipyard/ipfs-deploy-action/blob/main/docs/recipes/filebase.md"
[storacha-key]="Storacha service was sunset on 2026-04-15. Pick another service from https://github.com/ipshipyard/ipfs-deploy-action/blob/main/docs/recipes/"
[storacha-proof]="Storacha service was sunset on 2026-04-15. Pick another service from https://github.com/ipshipyard/ipfs-deploy-action/blob/main/docs/recipes/"
)
{
echo "## v2 migration required"
echo
echo "You are passing inputs that v2 removed. Apply the per-input migration below."
echo
echo "| Removed input | Migration |"
echo "| ------------- | --------- |"
for input in "${REMOVED[@]}"; do
echo "| \`${input}\` | ${POINTERS[$input]} |"
done
echo
echo "Full v2 release notes: https://github.com/ipshipyard/ipfs-deploy-action/blob/main/CHANGELOG.md"
} >> "$GITHUB_STEP_SUMMARY"
echo "::error::v2 removed the inputs: ${REMOVED[*]}. See the job summary for per-input migration links."
exit 1
- name: Validate native provider config
shell: bash
# INPUT_ prefix avoids collision with user-defined env vars or secrets.
env:
INPUT_CLUSTER_URL: ${{ inputs.cluster-url }}
INPUT_CLUSTER_USER: ${{ inputs.cluster-user }}
INPUT_CLUSTER_PASSWORD: ${{ inputs.cluster-password }}
INPUT_CLUSTER_RETRY_ATTEMPTS: ${{ inputs.cluster-retry-attempts }}
INPUT_KUBO_API_URL: ${{ inputs.kubo-api-url }}
INPUT_KUBO_API_AUTH: ${{ inputs.kubo-api-auth }}
run: |
# IPFS Cluster requires all three: url, user, password. Either all set or all empty.
if [ -n "$INPUT_CLUSTER_URL$INPUT_CLUSTER_USER$INPUT_CLUSTER_PASSWORD" ] && \
{ [ -z "$INPUT_CLUSTER_URL" ] || [ -z "$INPUT_CLUSTER_USER" ] || [ -z "$INPUT_CLUSTER_PASSWORD" ]; }; then
echo "::error::IPFS Cluster config is incomplete. Set all three: cluster-url, cluster-user, cluster-password, or leave all empty to skip Cluster pinning."
exit 1
fi
# The Cluster upload step iterates $(seq 1 attempts); zero or a
# non-numeric value would run zero attempts and fail without ever
# contacting the cluster.
if [ -n "$INPUT_CLUSTER_URL" ]; then
if ! [[ "$INPUT_CLUSTER_RETRY_ATTEMPTS" =~ ^[0-9]+$ ]] || [[ "$INPUT_CLUSTER_RETRY_ATTEMPTS" =~ ^0+$ ]]; then
echo "::error::cluster-retry-attempts must be a positive integer. Got: '$INPUT_CLUSTER_RETRY_ATTEMPTS'"
exit 1
fi
fi
# Kubo RPC pinning requires both: url and auth. Either both set or both empty.
if [ -n "$INPUT_KUBO_API_URL$INPUT_KUBO_API_AUTH" ] && \
{ [ -z "$INPUT_KUBO_API_URL" ] || [ -z "$INPUT_KUBO_API_AUTH" ]; }; then
echo "::error::Kubo config is incomplete. Set both: kubo-api-url, kubo-api-auth, or leave both empty to skip Kubo pinning."
exit 1
fi
- name: Setup Kubo CLI
uses: ipfs/download-ipfs-distribution-action@v2
with:
name: kubo
version: ${{ inputs.kubo-version }}
- name: ipfs init
shell: bash
# ipfs init is required to use many of the ipfs commands
run: |
# Guarded so the action can run more than once in the same job:
# a second `ipfs init` against an existing repo exits 1.
[ -e "${IPFS_PATH:-$HOME/.ipfs}/config" ] || ipfs init
- name: Apply Kubo CID profile
if: ${{ inputs.cid-profile != '' }}
shell: bash
env:
CID_PROFILE: ${{ inputs.cid-profile }}
run: |
case "$CID_PROFILE" in
unixfs-v1-2025|unixfs-v0-2015)
;;
*)
echo "::error::cid-profile must be 'unixfs-v1-2025', 'unixfs-v0-2015', or '' (empty). Got: $CID_PROFILE"
exit 1
;;
esac
ipfs config profile apply "$CID_PROFILE"
echo "ℹ️ Applied Kubo profile \`$CID_PROFILE\`" >> "$GITHUB_STEP_SUMMARY"
- name: Merkleize into CAR file
id: merkleize
shell: bash
env:
PATH_TO_DEPLOY: ${{ inputs.path-to-deploy }}
# Passed unquoted below so multiple options word-split into separate args.
IPFS_ADD_OPTIONS: ${{ inputs.ipfs-add-options }}
CAR_FILE_NAME: ${{ inputs.car-file-name }}
run: |
echo "ℹ️ Merkleizing $PATH_TO_DEPLOY into CAR file"
if [ ! -d "$PATH_TO_DEPLOY" ]; then
echo "::error::Directory '$PATH_TO_DEPLOY' does not exist or is not accessible"
exit 1
fi
if [ -z "$(ls -A "$PATH_TO_DEPLOY")" ]; then
echo "::error::Directory '$PATH_TO_DEPLOY' is empty"
exit 1
fi
CID=$(ipfs add $IPFS_ADD_OPTIONS -Q -r "$PATH_TO_DEPLOY")
if [ -z "$CID" ]; then
echo "::error::ipfs add returned an empty CID"
exit 1
fi
ipfs dag export "$CID" > "$CAR_FILE_NAME"
{
echo "cid=$CID"
echo "car-path=$CAR_FILE_NAME"
} >> "$GITHUB_OUTPUT"
echo "Root CID: $CID"
echo "✅ Merkleized \`$PATH_TO_DEPLOY\` into CAR file \`$CAR_FILE_NAME\` with root CID \`$CID\`" >> "$GITHUB_STEP_SUMMARY"
- name: CAR file artifact name
id: car-artifact
if: ${{ inputs.upload-car-artifact != 'false' }}
shell: bash
env:
REPOSITORY: ${{ github.repository }}
COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.event.workflow_run.head_sha || github.sha }}
CID: ${{ steps.merkleize.outputs.cid }}
run: |
# The name embeds the CID, so equal names always carry identical
# bytes; that is what makes `overwrite` in the upload step lossless.
echo "name=${REPOSITORY//\//-}-${COMMIT_SHA:0:7}-${CID}.car" >> "$GITHUB_OUTPUT"
- name: CAR file artifact upload
if: ${{ inputs.upload-car-artifact != 'false' }}
uses: actions/upload-artifact@v7
with:
name: ${{ steps.car-artifact.outputs.name }}
path: ${{ inputs.car-file-name }}
retention-days: 7
if-no-files-found: error
overwrite: true
- name: Upload CAR to Kubo
if: ${{ inputs.kubo-api-url != '' && inputs.kubo-api-auth != ''}}
shell: bash
env:
INPUT_KUBO_API_URL: ${{ inputs.kubo-api-url }}
INPUT_KUBO_API_AUTH: ${{ inputs.kubo-api-auth }}
CAR_FILE_NAME: ${{ inputs.car-file-name }}
CID: ${{ steps.merkleize.outputs.cid }}
run: |
echo "ℹ️ Uploading CAR with CID $CID to Kubo"
if [ -n "$ACTIONS_RUNNER_DEBUG" ]; then
export GOLOG_LOG_LEVEL=debug
fi
ipfs dag import "$CAR_FILE_NAME" --api "$INPUT_KUBO_API_URL" --api-auth "$INPUT_KUBO_API_AUTH"
echo "✅ Uploaded CAR with CID $CID to Kubo" >> "$GITHUB_STEP_SUMMARY"
- name: Setup IPFS Cluster CLI
if: ${{ inputs.cluster-url != ''}}
uses: ipfs/download-ipfs-distribution-action@v2
with:
name: ipfs-cluster-ctl
version: ${{ inputs.ipfs-cluster-ctl-version }}
- name: Upload CAR to IPFS Cluster
if: ${{ inputs.cluster-url != '' && inputs.cluster-user != '' && inputs.cluster-password != '' }}
shell: bash
env:
INPUT_CLUSTER_URL: ${{ inputs.cluster-url }}
INPUT_CLUSTER_USER: ${{ inputs.cluster-user }}
INPUT_CLUSTER_PASSWORD: ${{ inputs.cluster-password }}
CAR_FILE_NAME: ${{ inputs.car-file-name }}
CID: ${{ steps.merkleize.outputs.cid }}
REPOSITORY: ${{ github.repository }}
COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.event.workflow_run.head_sha || github.sha }}
PIN_NAME_INPUT: ${{ inputs.pin-name }}
PIN_EXPIRE_IN: ${{ inputs.cluster-pin-expire-in }}
RETRY_ATTEMPTS: ${{ inputs.cluster-retry-attempts }}
TIMEOUT_MINUTES: ${{ inputs.cluster-timeout-minutes }}
run: |
echo "ℹ️ Uploading CAR with CID $CID to IPFS Cluster"
pin_name="${PIN_NAME_INPUT:-${REPOSITORY//\//-}-${COMMIT_SHA:0:7}}"
expire_args=()
if [ -n "$PIN_EXPIRE_IN" ]; then
expire_args=(--expire-in "$PIN_EXPIRE_IN")
fi
for attempt in $(seq 1 "$RETRY_ATTEMPTS"); do
echo "Attempt #$attempt of $RETRY_ATTEMPTS"
# Raise log verbosity from the second attempt on to help diagnose a flaky cluster.
if [ -n "$ACTIONS_RUNNER_DEBUG" ] || [ "$attempt" -ge 2 ]; then
export GOLOG_LOG_LEVEL=debug
fi
# --local adds the CAR to the peer receiving the request without waiting
# for it to replicate across the rest of the cluster.
if timeout "${TIMEOUT_MINUTES}m" ipfs-cluster-ctl \
--enc=json \
--host "$INPUT_CLUSTER_URL" \
--basic-auth "${INPUT_CLUSTER_USER}:${INPUT_CLUSTER_PASSWORD}" \
add --format=car \
--local \
--name "$pin_name" \
"${expire_args[@]}" \
"$CAR_FILE_NAME"; then
echo "✅ Uploaded CAR with CID $CID to IPFS Cluster" >> "$GITHUB_STEP_SUMMARY"
if [ -n "$PIN_EXPIRE_IN" ]; then
echo "⏰ IPFS Cluster pin expires in $PIN_EXPIRE_IN" >> "$GITHUB_STEP_SUMMARY"
fi
exit 0
fi
echo "Attempt #$attempt failed"
if [ "$attempt" -lt "$RETRY_ATTEMPTS" ]; then
sleep 5
fi
done
echo "❌ Failed to upload CAR with CID $CID to IPFS Cluster after $RETRY_ATTEMPTS attempts" >> "$GITHUB_STEP_SUMMARY"
exit 1
- name: Compute reporting flags
id: report
shell: bash
env:
SET_GITHUB_STATUS: ${{ inputs.set-github-status }}
SET_PR_COMMENT: ${{ inputs.set-pr-comment }}
INPUT_KUBO_API_URL: ${{ inputs.kubo-api-url }}
INPUT_CLUSTER_URL: ${{ inputs.cluster-url }}
run: |
# Auto-enable PR comment and commit status when Kubo or IPFS Cluster is configured.
# Explicit 'true' or 'false' input overrides the auto rule.
auto="false"
if [ -n "$INPUT_KUBO_API_URL" ] || [ -n "$INPUT_CLUSTER_URL" ]; then
auto="true"
fi
resolve() {
case "$1" in
true|false) printf '%s' "$1" ;;
"") printf '%s' "$auto" ;;
*) return 1 ;;
esac
}
if ! status=$(resolve "$SET_GITHUB_STATUS"); then
echo "::error::set-github-status must be 'true', 'false', or empty. Got: $SET_GITHUB_STATUS"
exit 1
fi
if ! comment=$(resolve "$SET_PR_COMMENT"); then
echo "::error::set-pr-comment must be 'true', 'false', or empty. Got: $SET_PR_COMMENT"
exit 1
fi
{
echo "set-github-status=$status"
echo "set-pr-comment=$comment"
} >> "$GITHUB_OUTPUT"
- name: Set GitHub commit status
if: ${{ steps.report.outputs.set-github-status == 'true' }}
uses: actions/github-script@v8
with:
github-token: ${{ inputs.github-token }}
script: |
const cid = '${{ steps.merkleize.outputs.cid }}';
// Determine the correct SHA based on the event type
let sha;
if (context.eventName === 'workflow_run') {
// For workflow_run events triggered by PRs, use the PR's head SHA
sha = context.payload.workflow_run.head_sha;
} else if (context.eventName === 'pull_request' || context.eventName === 'pull_request_target') {
// For PR events, use the head SHA
sha = context.payload.pull_request.head.sha;
} else {
// For push events, use the commit SHA
sha = context.sha;
}
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: sha,
state: 'success',
target_url: `https://${{ inputs.github-status-gw }}/ipfs/${cid}`,
description: `CID: ${cid}`,
context: 'IPFS'
});
- name: Get PR number for workflow_run
if: ${{ steps.report.outputs.set-pr-comment == 'true' && github.event_name == 'workflow_run' }}
id: pr-number
uses: actions/github-script@v8
with:
github-token: ${{ inputs.github-token }}
script: |
// For workflow_run events, we need to find the PR number from the workflow run
if (context.payload.workflow_run.event === 'pull_request') {
const pulls = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: `${context.payload.workflow_run.head_repository.owner.login}:${context.payload.workflow_run.head_branch}`,
state: 'open'
});
if (pulls.data.length > 0) {
// Try to find the PR whose head SHA matches the workflow run's head_sha
const matchingPr = pulls.data.find(pr => pr.head.sha === context.payload.workflow_run.head_sha);
if (matchingPr) {
core.setOutput('number', matchingPr.number);
core.setOutput('sha', matchingPr.head.sha);
} else {
// Fallback: use the first PR, but warn in the summary
core.setOutput('number', pulls.data[0].number);
core.setOutput('sha', context.payload.workflow_run.head_sha);
core.warning(`Multiple PRs found for branch ${context.payload.workflow_run.head_branch}, but none matched head_sha. Using the first PR (#${pulls.data[0].number}).`);
}
} else {
core.warning(`No open PRs found for branch ${context.payload.workflow_run.head_branch} from ${context.payload.workflow_run.head_repository.owner.login}`);
}
}
- name: Find Comment to update
if: ${{ steps.report.outputs.set-pr-comment == 'true' && (github.event_name == 'pull_request' || github.event_name == 'pull_request_target' || (github.event_name == 'workflow_run' && steps.pr-number.outputs.number)) }}
uses: peter-evans/find-comment@v4
id: fc
with:
issue-number: ${{ github.event.pull_request.number || steps.pr-number.outputs.number }}
comment-author: 'github-actions[bot]'
body-includes: '🚀 Build'
token: ${{ inputs.github-token }}
- name: Create or update comment
if: ${{ steps.report.outputs.set-pr-comment == 'true' && (github.event_name == 'pull_request' || github.event_name == 'pull_request_target' || (github.event_name == 'workflow_run' && steps.pr-number.outputs.number)) }}
uses: peter-evans/create-or-update-comment@v5
with:
token: ${{ inputs.github-token }}
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number || steps.pr-number.outputs.number }}
body: |
### 🚀 Build Preview on IPFS ready
- 🔎 Commit: ${{ github.event.pull_request.head.sha || steps.pr-number.outputs.sha }}
- 🔏 CID `${{ steps.merkleize.outputs.cid }}`
- 📦 Preview:
- [inbrowser.link](https://inbrowser.link/ipfs/${{ steps.merkleize.outputs.cid }})
edit-mode: replace