Skip to content

Commit 58fa808

Browse files
committed
Extract release workflow publishing steps into composite actions
1 parent 78e65f8 commit 58fa808

File tree

4 files changed

+192
-369
lines changed

4 files changed

+192
-369
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: NPM Auth Preflight
2+
description: Validate npm authentication and report package access
3+
4+
inputs:
5+
registry-url:
6+
description: npm registry URL
7+
required: false
8+
default: "https://registry.npmjs.org/"
9+
package-dir:
10+
description: Directory containing package.json to validate
11+
required: true
12+
package-name:
13+
description: Display name for error messages
14+
required: true
15+
16+
runs:
17+
using: composite
18+
steps:
19+
- name: Preflight npm auth
20+
shell: bash
21+
env:
22+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
23+
REGISTRY_URL: ${{ inputs.registry-url }}
24+
PACKAGE_DIR: ${{ inputs.package-dir }}
25+
PACKAGE_NAME: ${{ inputs.package-name }}
26+
run: |
27+
set -euo pipefail
28+
29+
if [[ -z "${NODE_AUTH_TOKEN:-}" ]]; then
30+
echo "::error::NPM_TOKEN is missing. Configure a publish-capable npm token for ${PACKAGE_NAME} before rerunning release."
31+
exit 1
32+
fi
33+
34+
pushd "$PACKAGE_DIR" >/dev/null
35+
npm config set //registry.npmjs.org/:_authToken "${NODE_AUTH_TOKEN}"
36+
npm_user=$(npm whoami --registry "$REGISTRY_URL")
37+
popd >/dev/null
38+
39+
echo "Authenticated to npm as ${npm_user}"
40+
echo "Deferring publish permission enforcement for ${PACKAGE_NAME} to the publish step because npm access output is not stable in this workflow."
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: NPM Publish Package
2+
description: Publish a package to npm with retry and verification logic
3+
4+
inputs:
5+
registry-url:
6+
description: npm registry URL
7+
required: false
8+
default: "https://registry.npmjs.org/"
9+
package-dir:
10+
description: Directory containing package.json to publish
11+
required: true
12+
verify-attempts:
13+
description: Number of verification attempts
14+
required: false
15+
default: "90"
16+
verify-delay:
17+
description: Delay between verification attempts in seconds
18+
required: false
19+
default: "10"
20+
21+
runs:
22+
using: composite
23+
steps:
24+
- name: Publish to npm
25+
shell: bash
26+
env:
27+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
28+
REGISTRY_URL: ${{ inputs.registry-url }}
29+
PACKAGE_DIR: ${{ inputs.package-dir }}
30+
VERIFY_ATTEMPTS: ${{ inputs.verify-attempts }}
31+
VERIFY_DELAY: ${{ inputs.verify-delay }}
32+
run: |
33+
set -euo pipefail
34+
35+
package_name=$(jq -r '.name' "${PACKAGE_DIR}/package.json")
36+
package_version=$(jq -r '.version' "${PACKAGE_DIR}/package.json")
37+
38+
registry_version_exists() {
39+
local encoded_package_name
40+
local version_json
41+
local published_version
42+
43+
encoded_package_name=$(node -e 'process.stdout.write(encodeURIComponent(process.argv[1]))' "$package_name")
44+
version_json=$(curl --silent --show-error --fail "${REGISTRY_URL%/}/${encoded_package_name}/${package_version}" 2>/dev/null || true)
45+
46+
if [[ -z "$version_json" ]]; then
47+
return 1
48+
fi
49+
50+
published_version=$(jq -r '.version // empty' <<<"$version_json")
51+
[[ "$published_version" == "$package_version" ]]
52+
}
53+
54+
version_exists() {
55+
local published_version
56+
published_version=$(npm view "${package_name}@${package_version}" version --registry "$REGISTRY_URL" 2>/dev/null || true)
57+
58+
if [[ "$published_version" == "$package_version" ]]; then
59+
return 0
60+
fi
61+
62+
registry_version_exists
63+
}
64+
65+
verify_version_exists() {
66+
local attempts="$VERIFY_ATTEMPTS"
67+
local delay_seconds="$VERIFY_DELAY"
68+
69+
for attempt in $(seq 1 "$attempts"); do
70+
if version_exists; then
71+
echo "Verified ${package_name}@${package_version} on npm"
72+
return 0
73+
fi
74+
75+
if [[ "$attempt" -eq "$attempts" ]]; then
76+
break
77+
fi
78+
79+
echo "Waiting for ${package_name}@${package_version} to appear on npm (${attempt}/${attempts})..."
80+
sleep "$delay_seconds"
81+
done
82+
83+
echo "::error::${package_name}@${package_version} is still missing from npm after publish."
84+
return 1
85+
}
86+
87+
if version_exists; then
88+
echo "${package_name}@${package_version} already exists on npm, skipping"
89+
exit 0
90+
fi
91+
92+
publish_log=$(mktemp)
93+
94+
if (cd "$PACKAGE_DIR" && pnpm publish --access public --no-git-checks) 2>&1 | tee "$publish_log"; then
95+
verify_version_exists
96+
rm -f "$publish_log"
97+
exit 0
98+
fi
99+
100+
if grep -Eiq 'cannot publish over the previously published versions|previously published versions' "$publish_log"; then
101+
echo "${package_name}@${package_version} was already published according to npm, skipping"
102+
rm -f "$publish_log"
103+
exit 0
104+
fi
105+
106+
if version_exists; then
107+
echo "${package_name}@${package_version} already exists on npm after publish attempt, skipping"
108+
rm -f "$publish_log"
109+
exit 0
110+
fi
111+
112+
echo "::error::Failed to publish ${package_name}@${package_version}. Exact version is still missing from npm."
113+
rm -f "$publish_log"
114+
exit 1
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Setup Cross-Compile Linux ARM64
2+
description: Install aarch64-linux-gnu cross-compilation toolchain
3+
4+
runs:
5+
using: composite
6+
steps:
7+
- name: Install cross-compilation tools (aarch64-linux)
8+
shell: bash
9+
run: |
10+
sudo apt-get update
11+
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
12+
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV

0 commit comments

Comments
 (0)