-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathaction.yml
More file actions
406 lines (377 loc) · 17.5 KB
/
Copy pathaction.yml
File metadata and controls
406 lines (377 loc) · 17.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
name: 'nsite-action'
description: 'Deploys static website files to Blossom/Nostr using the nsyte CLI.'
author: 'nsite-action Developers'
inputs:
version:
description: 'The version of the nsyte CLI to use (e.g., "v0.5.3", "latest"). Needs to match a tag in github.com/sandwichfarm/nsyte/releases'
required: false
default: 'latest'
sec:
description: 'Compatibility input. Prefer nbunksec; this value is still passed to nsyte via --sec.'
required: false
nbunksec:
description: 'Recommended CI signing credential. Must start with nbunksec1; this action rejects sec1 values to discourage direct private key usage.'
required: false
directory:
description: 'The directory containing the static files to deploy.'
required: true
relays:
description: 'Newline-separated list of Nostr relay WebSocket URIs to publish the site event to.'
required: false
default: ''
servers:
description: 'Newline-separated list of Blossom server HTTPS URLs to deploy files to.'
required: false
default: ''
name:
description: 'Deploy as a named nsite (NIP-5A). When set, the site is published under this name via --name. When omitted, the site deploys as the root (npub) nsite.'
required: false
default: ''
force:
description: 'Corresponds to the --force flag in nsyte deploy. Re-deploy all files.'
required: false
default: 'false'
purge:
description: 'DEPRECATED: There is no deploy-time purge flag in nsyte. Use the nsyte "delete" or "undeploy" commands instead.'
required: false
default: 'false'
sync:
description: 'Corresponds to the --sync flag in nsyte deploy. Check all servers and upload missing blobs.'
required: false
default: 'false'
verbose:
description: 'Corresponds to the --verbose flag in nsyte deploy. Show detailed output.'
required: false
default: 'false'
concurrency:
description: 'Corresponds to the --concurrency flag in nsyte deploy. Number of parallel deploys.'
required: false
default: '4'
fallback:
description: 'Corresponds to the --fallback flag in nsyte deploy. Path to the fallback HTML file (e.g., /index.html for SPAs).'
required: false
default: ''
publish_server_list:
description: 'true/false. If true, the server list will be published to relays. Root sites only.'
required: false
default: 'false'
publish_relay_list:
description: 'true/false. If true, the relay list will be published to relays. Root sites only.'
required: false
default: 'false'
publish_profile:
description: 'true/false. If true, the profile will be published to relays. Root sites only.'
required: false
default: 'false'
use_fallback_relays:
description: 'If true, include default nsyte relays in addition to configured ones.'
required: false
default: 'false'
use_fallback_servers:
description: 'If true, include default nsyte blossom servers in addition to configured ones.'
required: false
default: 'false'
publish_app_handler:
description: 'If true, publish NIP-89 app handler announcement (Kind 31990).'
required: false
default: 'false'
handler_kinds:
description: 'Comma-separated event kinds the nsite can handle. Only used when publish_app_handler is true.'
required: false
default: ''
skip_secrets_scan:
description: 'If true (default), pass --skip-secrets-scan to nsyte to bypass the pre-deploy secrets scan. Set to "false" to let nsyte scan the deploy directory for credentials before publishing. Requires an nsyte version that supports the flag; ignored automatically on older versions.'
required: false
default: 'true'
scan_level:
description: 'Secrets scan sensitivity passed to nsyte via --scan-level (low, medium, high). Only applied when skip_secrets_scan is false. Leave blank to use the nsyte default.'
required: false
default: ''
outputs:
status:
description: 'Status of the deploy operation (e.g., "success").'
value: ${{ steps.nsyte_run.outputs.status }}
nsyte_version_used:
description: 'The actual version of nsyte that was downloaded and used.'
value: ${{ steps.nsyte_run.outputs.nsyte_version_used }}
branding:
icon: 'upload-cloud'
color: 'purple'
runs:
using: 'composite'
steps:
- name: Determine Platform
id: platform
shell: bash
run: |
PLATFORM=""
ARCH_SUFFIX=""
EXE_SUFFIX=""
if [[ "${{ runner.os }}" == "Linux" ]]; then PLATFORM="linux";
elif [[ "${{ runner.os }}" == "macOS" ]]; then
PLATFORM="macos"
RUNNER_ARCH="$(uname -m)"
if [[ "$RUNNER_ARCH" == "arm64" ]]; then ARCH_SUFFIX="-arm64";
elif [[ "$RUNNER_ARCH" == "x86_64" ]]; then ARCH_SUFFIX="-x64";
else echo "::error::Unsupported macOS architecture: $RUNNER_ARCH"; exit 1; fi
elif [[ "${{ runner.os }}" == "Windows" ]]; then PLATFORM="windows"; EXE_SUFFIX=".exe";
else echo "::error::Unsupported runner OS: ${{ runner.os }}"; exit 1; fi
echo "Detected platform: $PLATFORM$ARCH_SUFFIX"
echo "platform=$PLATFORM" >> $GITHUB_OUTPUT
echo "arch_suffix=$ARCH_SUFFIX" >> $GITHUB_OUTPUT
echo "exe_suffix=$EXE_SUFFIX" >> $GITHUB_OUTPUT
- name: Ensure jq is installed
shell: bash
run: |
set -e
if [[ "${{ steps.platform.outputs.platform }}" == "linux" ]]; then
if ! command -v jq &> /dev/null; then
echo "jq not found, installing via apt-get..."
sudo apt-get update && sudo apt-get install -y jq
else
echo "jq is already installed."
fi
elif [[ "${{ steps.platform.outputs.platform }}" == "macos" ]]; then
if ! command -v jq &> /dev/null; then
echo "jq not found, installing via brew..."
brew install jq
else
echo "jq is already installed."
fi
elif [[ "${{ steps.platform.outputs.platform }}" == "windows" ]]; then
if ! command -v jq &> /dev/null; then
echo "jq not found, installing via choco..."
choco install jq -y
export PATH="$PATH:/c/ProgramData/chocolatey/bin"
else
echo "jq is already installed."
fi
else
echo "Unknown platform for jq installation."
exit 1
fi
- name: Set nsyte Version
id: version
shell: bash
run: |
NSYT_VERSION_INPUT="${{ inputs.version }}"
NSYT_VERSION_FINAL=""
VERSION_NUMBER=""
if [[ "$NSYT_VERSION_INPUT" == "latest" ]]; then
echo "Input version is 'latest', resolving..."
LATEST_TAG=""
# Try GH CLI first: it respects the "latest" flag set in GitHub UI if --limit 1 is used.
if command -v gh &> /dev/null && gh auth status &> /dev/null; then
echo "Using 'gh' CLI to find latest release."
LATEST_TAG=$(gh release list -R sandwichfarm/nsyte --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null)
fi
# Fallback to curl /releases/latest endpoint if gh failed or not available/authed
if [[ -z "$LATEST_TAG" ]]; then
echo "Using GitHub API (curl) to find latest release (gh CLI failed or not available/authed)."
LATEST_TAG=$(curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/sandwichfarm/nsyte/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d '"' -f 4)
fi
# If still no tag, try the semantic sort as a robust last resort (requires sort -V, usually on Linux)
if [[ -z "$LATEST_TAG" || "$LATEST_TAG" == "null" ]]; then
echo "Fallback: Attempting semantic version sort of all release tags."
ALL_TAGS=$(gh release list -R sandwichfarm/nsyte --json tagName --jq '.[].tagName' 2>/dev/null)
if [[ -n "$ALL_TAGS" ]]; then
LATEST_TAG=$(echo "$ALL_TAGS" | grep '^v[0-9]' | sort -V | tail -n 1)
fi
fi
if [[ -z "$LATEST_TAG" || "$LATEST_TAG" == "null" ]]; then echo "::error::Failed to determine latest nsyte release tag."; exit 1; fi
NSYT_VERSION_FINAL="$LATEST_TAG"
echo "Resolved latest version: $NSYT_VERSION_FINAL"
else
NSYT_VERSION_FINAL="${{ inputs.version }}"
echo "Using specified version: $NSYT_VERSION_FINAL"
fi
# Extract version number for asset filename
if [[ "$NSYT_VERSION_FINAL" =~ ^v(.+)$ ]]; then VERSION_NUMBER="${BASH_REMATCH[1]}"; else VERSION_NUMBER="$NSYT_VERSION_FINAL"; fi
echo "Using nsyte tag: $NSYT_VERSION_FINAL (version number for asset: $VERSION_NUMBER)"
# Using ::set-output for version outputs as GITHUB_OUTPUT can be finicky in composite actions
#echo "::set-output name=version::${NSYT_VERSION_FINAL}"
#echo "::set-output name=version_number::${VERSION_NUMBER}"
echo "version=${NSYT_VERSION_FINAL}" >> $GITHUB_OUTPUT
echo "version_number=${VERSION_NUMBER}" >> $GITHUB_OUTPUT
- name: Download nsyte
id: download_nsyte
shell: bash
run: |
VERSION_TAG="${{ steps.version.outputs.version }}"
VERSION_NUMBER="${{ steps.version.outputs.version_number }}"
PLATFORM="${{ steps.platform.outputs.platform }}"
ARCH_SUFFIX="${{ steps.platform.outputs.arch_suffix }}"
EXE_SUFFIX="${{ steps.platform.outputs.exe_suffix }}"
mkdir -p nsyte_bin
ASSET_CANDIDATES=()
if [[ "$PLATFORM" == "macos" ]]; then
ASSET_CANDIDATES+=("nsyte-$PLATFORM$ARCH_SUFFIX-$VERSION_NUMBER$EXE_SUFFIX")
ASSET_CANDIDATES+=("nsyte-$PLATFORM$ARCH_SUFFIX$EXE_SUFFIX")
else
ASSET_CANDIDATES+=("nsyte-$PLATFORM-$VERSION_NUMBER$EXE_SUFFIX")
ASSET_CANDIDATES+=("nsyte-$PLATFORM$EXE_SUFFIX")
fi
ASSET_FILENAME=""
for CANDIDATE in "${ASSET_CANDIDATES[@]}"; do
DOWNLOAD_URL="https://github.com/sandwichfarm/nsyte/releases/download/$VERSION_TAG/$CANDIDATE"
echo "Trying nsyte asset $CANDIDATE from $DOWNLOAD_URL"
HTTP_STATUS=$(curl -sL -w "%{http_code}" -o "nsyte_bin/$CANDIDATE" "$DOWNLOAD_URL")
if [[ "$HTTP_STATUS" == "200" ]]; then
ASSET_FILENAME="$CANDIDATE"
break
fi
rm -f "nsyte_bin/$CANDIDATE"
done
if [[ -z "$ASSET_FILENAME" ]]; then
echo "::error::Failed to download a compatible nsyte asset for version '$VERSION_TAG'."
echo "Tried assets: ${ASSET_CANDIDATES[*]}"
if command -v gh &> /dev/null && gh auth status &> /dev/null; then
gh release view "$VERSION_TAG" -R sandwichfarm/nsyte --json assets --jq '.assets[].name' 2>/dev/null || echo "(Could not list assets with gh CLI)"
else
curl -s "https://api.github.com/repos/sandwichfarm/nsyte/releases/tags/$VERSION_TAG" | grep '"name":' | cut -d '"' -f 4 || echo "(Could not list assets with API)"
fi
exit 1
fi
echo "Downloaded nsyte asset: $ASSET_FILENAME"
chmod +x "nsyte_bin/$ASSET_FILENAME"
# Using ::set-output for nsyte_path
#echo "::set-output name=nsyte_path::$(pwd)/nsyte_bin/$ASSET_FILENAME"
echo "nsyte_path=$(pwd)/nsyte_bin/$ASSET_FILENAME" >> $GITHUB_OUTPUT
- name: Run nsyte deploy
id: nsyte_run
shell: bash
env:
NSYTE_PATH: ${{ steps.download_nsyte.outputs.nsyte_path }}
NSYTE_VERSION: ${{ steps.version.outputs.version }}
INPUT_SEC: ${{ inputs.sec }}
INPUT_NBUNKSEC: ${{ inputs.nbunksec }}
INPUT_DIRECTORY: ${{ inputs.directory }}
INPUT_RELAYS: ${{ inputs.relays }}
INPUT_SERVERS: ${{ inputs.servers }}
INPUT_NAME: ${{ inputs.name }}
INPUT_FORCE: ${{ inputs.force }}
INPUT_SYNC: ${{ inputs.sync }}
INPUT_VERBOSE: ${{ inputs.verbose }}
INPUT_FALLBACK: ${{ inputs.fallback }}
INPUT_CONCURRENCY: ${{ inputs.concurrency }}
INPUT_PUBLISH_SERVER_LIST: ${{ inputs.publish_server_list }}
INPUT_PUBLISH_RELAY_LIST: ${{ inputs.publish_relay_list }}
INPUT_PUBLISH_PROFILE: ${{ inputs.publish_profile }}
INPUT_USE_FALLBACK_RELAYS: ${{ inputs.use_fallback_relays }}
INPUT_USE_FALLBACK_SERVERS: ${{ inputs.use_fallback_servers }}
INPUT_PUBLISH_APP_HANDLER: ${{ inputs.publish_app_handler }}
INPUT_HANDLER_KINDS: ${{ inputs.handler_kinds }}
INPUT_SKIP_SECRETS_SCAN: ${{ inputs.skip_secrets_scan }}
INPUT_SCAN_LEVEL: ${{ inputs.scan_level }}
run: |
set +e # Disable exit on error to manually handle exit codes and ensure outputs are set
join_nonblank_lines() {
awk '
{
gsub(/^[[:space:]]+|[[:space:]]+$/, "")
if (length($0) > 0) {
printf "%s%s", sep, $0
sep = ","
}
}
' <<< "$1"
}
print_masked_command() {
local -a masked_cmd=("$@")
local i
for ((i = 0; i < ${#masked_cmd[@]}; i++)); do
case "${masked_cmd[$i]}" in
--sec|--relays|--servers)
if ((i + 1 < ${#masked_cmd[@]})); then
masked_cmd[$((i + 1))]="***MASKED***"
fi
;;
esac
done
printf '%q ' "${masked_cmd[@]}"
printf '\n'
}
NBUNKSEC_VALUE="$INPUT_NBUNKSEC"
if [[ -n "$NBUNKSEC_VALUE" ]]; then
if [[ "$NBUNKSEC_VALUE" == sec1* ]]; then
echo "::error::The 'nbunksec' input must not be a sec1 private key. Generate a CI credential with 'nsyte ci' and use the resulting nbunksec1 value instead."
exit 1
fi
if [[ "$NBUNKSEC_VALUE" != nbunksec1* ]]; then
echo "::error::The 'nbunksec' input must start with 'nbunksec1'."
exit 1
fi
fi
# Pass either compatibility input through nsyte's --sec flag
SEC_VALUE="$INPUT_SEC"
if [[ -z "$SEC_VALUE" ]]; then
SEC_VALUE="$INPUT_NBUNKSEC"
fi
# The -i flag is critical for non-interactive CI environments.
CMD=("$NSYTE_PATH" deploy "$INPUT_DIRECTORY" -i --sec "$SEC_VALUE")
# Handle relays as newline-separated list
if [[ -n "$INPUT_RELAYS" ]]; then
RELAYS_CSV=$(join_nonblank_lines "$INPUT_RELAYS")
if [[ -n "$RELAYS_CSV" ]]; then
CMD+=(--relays "$RELAYS_CSV")
fi
fi
# Handle servers as newline-separated list
if [[ -n "$INPUT_SERVERS" ]]; then
SERVERS_CSV=$(join_nonblank_lines "$INPUT_SERVERS")
if [[ -n "$SERVERS_CSV" ]]; then
CMD+=(--servers "$SERVERS_CSV")
fi
fi
if [[ -n "$INPUT_NAME" ]]; then CMD+=(--name "$INPUT_NAME"); fi
if [[ "$INPUT_FORCE" == "true" ]]; then CMD+=(--force); fi
if [[ "$INPUT_SYNC" == "true" ]]; then CMD+=(--sync); fi
if [[ "$INPUT_VERBOSE" == "true" ]]; then CMD+=(--verbose); fi
if [[ -n "$INPUT_FALLBACK" ]]; then CMD+=(--fallback "$INPUT_FALLBACK"); fi
if [[ -n "$INPUT_CONCURRENCY" ]]; then CMD+=(--concurrency "$INPUT_CONCURRENCY"); fi
if [[ "$INPUT_PUBLISH_SERVER_LIST" == "true" ]]; then CMD+=(--publish-server-list); fi
if [[ "$INPUT_PUBLISH_RELAY_LIST" == "true" ]]; then CMD+=(--publish-relay-list); fi
if [[ "$INPUT_PUBLISH_PROFILE" == "true" ]]; then CMD+=(--publish-profile); fi
if [[ "$INPUT_USE_FALLBACK_RELAYS" == "true" ]]; then CMD+=(--use-fallback-relays); fi
if [[ "$INPUT_USE_FALLBACK_SERVERS" == "true" ]]; then CMD+=(--use-fallback-servers); fi
if [[ "$INPUT_PUBLISH_APP_HANDLER" == "true" ]]; then CMD+=(--publish-app-handler); fi
if [[ -n "$INPUT_HANDLER_KINDS" ]]; then CMD+=(--handler-kinds "$INPUT_HANDLER_KINDS"); fi
# Secrets scan controls. Feature-detect against `nsyte deploy --help` so older
# nsyte versions (which have neither the scan nor the flag) still work.
NSYTE_HELP=$("$NSYTE_PATH" deploy --help 2>&1 || true)
if [[ "$INPUT_SKIP_SECRETS_SCAN" == "true" ]]; then
if echo "$NSYTE_HELP" | grep -q -- '--skip-secrets-scan'; then
CMD+=(--skip-secrets-scan)
else
echo "Note: nsyte version does not support --skip-secrets-scan; nothing to skip."
fi
elif [[ -n "$INPUT_SCAN_LEVEL" ]]; then
if echo "$NSYTE_HELP" | grep -q -- '--scan-level'; then
CMD+=(--scan-level "$INPUT_SCAN_LEVEL")
else
echo "Note: nsyte version does not support --scan-level; ignoring scan_level input."
fi
fi
echo "nsyte_version_used=$NSYTE_VERSION" >> $GITHUB_OUTPUT
echo "Executing nsyte command (secrets masked):"
print_masked_command "${CMD[@]}"
"${CMD[@]}"
COMMAND_EXIT_CODE=$? # Capture the exit code of the nsyte command
echo "COMMAND_EXIT_CODE=$COMMAND_EXIT_CODE"
if [[ $COMMAND_EXIT_CODE -eq 0 ]]; then
echo "nsyte deploy completed successfully."
#echo "::set-output name=status::success"
echo "status=success" >> $GITHUB_OUTPUT
else
echo "::error::nsyte deploy command failed with exit code $COMMAND_EXIT_CODE." # Log the error
#echo "::set-output name=status::failure"
echo "status=failure" >> $GITHUB_OUTPUT
fi
echo "exit_code=$COMMAND_EXIT_CODE" >> $GITHUB_OUTPUT
exit 0
- name: Fail composite action on nsyte error
if: ${{ steps.nsyte_run.outputs.exit_code != '0' }}
shell: bash
run: |
echo "Failing action because nsyte exited with code ${{ steps.nsyte_run.outputs.exit_code }}."
exit 1