-
Notifications
You must be signed in to change notification settings - Fork 3
183 lines (177 loc) · 8.16 KB
/
Copy pathrelease-pi.yml
File metadata and controls
183 lines (177 loc) · 8.16 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
# SPDX-License-Identifier: Apache-2.0
name: Release Pi package
on:
workflow_dispatch:
inputs:
ref:
description: Git ref to release
required: false
default: main
type: string
core_version:
description: Exact @nodedb-lab/code2graph version (for example 0.0.0-beta.8)
required: true
type: string
pi_version:
description: Exact @nodedb-lab/pi-code2graph version (for example 0.1.1)
required: true
type: string
permissions:
contents: read
concurrency:
group: release-pi-${{ inputs.pi_version }}
cancel-in-progress: false
jobs:
publish:
runs-on: ubuntu-latest
environment: npm
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.ref }}
fetch-depth: 0
- uses: actions/setup-node@v5
with:
node-version: "22"
registry-url: https://registry.npmjs.org
- name: Validate inputs and resolve immutable source
shell: bash
env:
CORE_VERSION: ${{ inputs.core_version }}
PI_VERSION: ${{ inputs.pi_version }}
run: |
set -euo pipefail
node bindings/pi/scripts/stage-release.mjs validate "$CORE_VERSION" core_version
node bindings/pi/scripts/stage-release.mjs validate "$PI_VERSION" pi_version
SOURCE_SHA="$(git rev-parse --verify "HEAD^{commit}")"
printf 'SOURCE_SHA=%s\nCORE_VERSION=%s\nPI_VERSION=%s\nPI_TAG=pi-v%s\n' "$SOURCE_SHA" "$CORE_VERSION" "$PI_VERSION" "$PI_VERSION" >> "$GITHUB_ENV"
- name: Confirm exact native package exists
shell: bash
run: |
set -euo pipefail
test "$(npm view "@nodedb-lab/code2graph@$CORE_VERSION" version)" = "$CORE_VERSION"
- name: Create and test isolated release staging tree
id: stage
shell: bash
run: |
set -euo pipefail
STAGE="$(mktemp -d)"
ARTIFACTS_DIR="$STAGE/artifacts"
mkdir -p "$STAGE/source" "$ARTIFACTS_DIR"
git archive --format=tar "$SOURCE_SHA" bindings/pi | tar -x -C "$STAGE/source"
PI_DIR="$STAGE/source/bindings/pi"
node bindings/pi/scripts/stage-release.mjs stamp "$PI_DIR/package.json" "$PI_VERSION" "$CORE_VERSION"
cd "$PI_DIR"
npm install --package-lock-only --save-exact "@nodedb-lab/code2graph@$CORE_VERSION"
node "$GITHUB_WORKSPACE/bindings/pi/scripts/stage-release.mjs" verify package.json package-lock.json "$PI_VERSION" "$CORE_VERSION"
npm ci
npm pack "@nodedb-lab/code2graph@$CORE_VERSION" --pack-destination "$ARTIFACTS_DIR"
npm pack --pack-destination "$ARTIFACTS_DIR"
shopt -s nullglob
pi_tarballs=("$ARTIFACTS_DIR"/nodedb-lab-pi-code2graph-*.tgz)
core_tarballs=("$ARTIFACTS_DIR"/nodedb-lab-code2graph-*.tgz)
test "${#pi_tarballs[@]}" -eq 1
test "${#core_tarballs[@]}" -eq 1
PI_TARBALL="${pi_tarballs[0]}"
CORE_TARBALL="${core_tarballs[0]}"
node "$GITHUB_WORKSPACE/bindings/pi/scripts/stage-release.mjs" inspect "$CORE_TARBALL" @nodedb-lab/code2graph "$CORE_VERSION"
node "$GITHUB_WORKSPACE/bindings/pi/scripts/stage-release.mjs" inspect "$PI_TARBALL" @nodedb-lab/pi-code2graph "$PI_VERSION" "$CORE_VERSION"
MANIFEST="$ARTIFACTS_DIR/SHA256SUMS"
{
printf '# source_sha=%s\n# core_version=%s\n# pi_version=%s\n' "$SOURCE_SHA" "$CORE_VERSION" "$PI_VERSION"
cd "$ARTIFACTS_DIR"
sha256sum "$(basename "$CORE_TARBALL")" "$(basename "$PI_TARBALL")"
} > "$MANIFEST"
{
printf 'stage=%s\n' "$STAGE"
printf 'artifacts_dir=%s\n' "$ARTIFACTS_DIR"
printf 'pi_dir=%s\n' "$PI_DIR"
printf 'pi_tarball=%s\n' "$PI_TARBALL"
printf 'core_tarball=%s\n' "$CORE_TARBALL"
printf 'manifest=%s\n' "$MANIFEST"
} >> "$GITHUB_OUTPUT"
- name: Test exact staged source and packed artifacts
shell: bash
env:
PI_DIR: ${{ steps.stage.outputs.pi_dir }}
CODE2GRAPH_PI_TARBALL: ${{ steps.stage.outputs.pi_tarball }}
CODE2GRAPH_CORE_TARBALL: ${{ steps.stage.outputs.core_tarball }}
run: |
set -euo pipefail
cd "$PI_DIR"
npm run typecheck
npm test
npm run test:pack
npm run test:smoke
- name: Upload tested release artifacts
uses: actions/upload-artifact@v7
with:
name: pi-release-${{ inputs.pi_version }}
path: ${{ steps.stage.outputs.artifacts_dir }}
retention-days: 14
- name: Publish tested tarball or verify existing release
shell: bash
env:
STAGE: ${{ steps.stage.outputs.stage }}
PI_TARBALL: ${{ steps.stage.outputs.pi_tarball }}
NPM_CONFIG_PROVENANCE: "true"
run: |
set -euo pipefail
NAME=@nodedb-lab/pi-code2graph
if npm view "$NAME@$PI_VERSION" version >/dev/null 2>&1; then
PUBLISH_DISPOSITION=already-published-identical
else
case "$PI_VERSION" in *-*) DIST_TAG=next ;; *) DIST_TAG=latest ;; esac
if npm publish "$PI_TARBALL" --access public --tag "$DIST_TAG" --provenance; then
PUBLISH_DISPOSITION="published-$DIST_TAG"
else
PUBLISH_DISPOSITION=publish-race-registry-verification
fi
fi
registry_version=
for _ in {1..30}; do
registry_version="$(npm view "$NAME@$PI_VERSION" version 2>/dev/null || true)"
test "$registry_version" = "$PI_VERSION" && break
sleep 2
done
test "$registry_version" = "$PI_VERSION" || { echo "$NAME@$PI_VERSION was not visible in the registry after polling" >&2; exit 1; }
npm view "$NAME@$PI_VERSION" dist.integrity dist.shasum --json | tee "$STAGE/artifacts/published-dist.json"
REMOTE_DIR="$STAGE/remote"
mkdir -p "$REMOTE_DIR"
npm pack "$NAME@$PI_VERSION" --pack-destination "$REMOTE_DIR"
shopt -s nullglob
remote_tarballs=("$REMOTE_DIR"/*.tgz)
test "${#remote_tarballs[@]}" -eq 1
REMOTE_TARBALL="${remote_tarballs[0]}"
node "$GITHUB_WORKSPACE/bindings/pi/scripts/stage-release.mjs" inspect "$REMOTE_TARBALL" "$NAME" "$PI_VERSION" "$CORE_VERSION"
node "$GITHUB_WORKSPACE/bindings/pi/scripts/stage-release.mjs" compare "$PI_TARBALL" "$REMOTE_TARBALL"
printf 'PUBLISH_DISPOSITION=%s\n' "$PUBLISH_DISPOSITION" >> "$GITHUB_ENV"
- name: Create or verify release tag after registry confirmation
shell: bash
run: |
set -euo pipefail
REMOTE_SHA="$(git ls-remote origin "refs/tags/$PI_TAG" "refs/tags/$PI_TAG^{}" | awk -v peeled="refs/tags/$PI_TAG^{}" '$2 == peeled {commit=$1} $2 != peeled {direct=$1} END {print commit ? commit : direct}')"
if test -z "$REMOTE_SHA"; then
git push origin "$SOURCE_SHA:refs/tags/$PI_TAG" || true
REMOTE_SHA="$(git ls-remote origin "refs/tags/$PI_TAG" "refs/tags/$PI_TAG^{}" | awk -v peeled="refs/tags/$PI_TAG^{}" '$2 == peeled {commit=$1} $2 != peeled {direct=$1} END {print commit ? commit : direct}')"
fi
test "$REMOTE_SHA" = "$SOURCE_SHA" || { echo "tag $PI_TAG points at ${REMOTE_SHA:-<missing>}, not $SOURCE_SHA" >&2; exit 1; }
echo "TAG_DISPOSITION=tag-confirmed" >> "$GITHUB_ENV"
- name: Release summary
shell: bash
env:
PI_TARBALL: ${{ steps.stage.outputs.pi_tarball }}
run: |
{
echo "## Pi release"
echo "- Pi: \`@nodedb-lab/pi-code2graph@$PI_VERSION\`"
echo "- Core: \`@nodedb-lab/code2graph@$CORE_VERSION\`"
echo "- Source: \`$SOURCE_SHA\`"
echo "- Tested artifact: \`$PI_TARBALL\`"
echo "- Publish: $PUBLISH_DISPOSITION"
echo "- Tag: $TAG_DISPOSITION (\`$PI_TAG\`)"
echo "- Rerun: Actions → Release Pi package → Run workflow with ref=${{ inputs.ref }}, core_version=$CORE_VERSION, pi_version=$PI_VERSION"
} >> "$GITHUB_STEP_SUMMARY"