Skip to content

Commit 2ff0ccf

Browse files
authored
ci: skip already published packages during release (#699)
* fix: skip already published packages during release * chore: simplify release publish skipping * fix: make release publish script portable * chore: remove NPM_TOKEN references * test: align provider github fixtures
1 parent a7f7f25 commit 2ff0ccf

2 files changed

Lines changed: 56 additions & 25 deletions

File tree

packages/provider-github/src/__tests__/providerGitHub.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const ARTIFACTS = [
1111
id: 123,
1212
name: 'rock-android-debug-1234567890',
1313
archive_download_url:
14-
'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/123',
14+
'https://api.github.com/repos/callstack/rock/actions/artifacts/123',
1515
size_in_bytes: 10000,
1616
expires_at: '2025-05-20T12:00:00Z',
1717
},
@@ -20,7 +20,7 @@ const ARTIFACTS = [
2020
id: 124,
2121
name: 'rock-android-debug-1234567890',
2222
archive_download_url:
23-
'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/124',
23+
'https://api.github.com/repos/callstack/rock/actions/artifacts/124',
2424
size_in_bytes: 10000,
2525
expires_at: '2025-05-20T12:00:00Z',
2626
},
@@ -41,7 +41,7 @@ test('providerGitHub implements list method returning an array of artifacts', as
4141
limit,
4242
});
4343
expect(fetch).toHaveBeenCalledWith(
44-
`https://api.github.com/repos/callstackincubator/rock/actions/artifacts?per_page=${limit}&page=1&name=rock-android-debug-1234567890`,
44+
`https://api.github.com/repos/callstack/rock/actions/artifacts?per_page=${limit}&page=1&name=rock-android-debug-1234567890`,
4545
{
4646
headers: {
4747
Authorization: 'token TEST_TOKEN',
@@ -52,7 +52,7 @@ test('providerGitHub implements list method returning an array of artifacts', as
5252
{
5353
id: '123',
5454
name: 'rock-android-debug-1234567890',
55-
url: 'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/123',
55+
url: 'https://api.github.com/repos/callstack/rock/actions/artifacts/123',
5656
},
5757
]);
5858
});
@@ -64,15 +64,15 @@ test('providerGitHub implements download method returning a stream with artifact
6464
global.fetch = vi.fn((url) => {
6565
if (
6666
url ===
67-
'https://api.github.com/repos/callstackincubator/rock/actions/artifacts?per_page=100&page=1&name=rock-android-debug-1234567890'
67+
'https://api.github.com/repos/callstack/rock/actions/artifacts?per_page=100&page=1&name=rock-android-debug-1234567890'
6868
) {
6969
return Promise.resolve(
7070
new Response(JSON.stringify({ artifacts: ARTIFACTS.slice(0, limit) })),
7171
);
7272
}
7373
if (
7474
url ===
75-
'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/123'
75+
'https://api.github.com/repos/callstack/rock/actions/artifacts/123'
7676
) {
7777
return Promise.resolve(downloadResponse);
7878
}
@@ -97,22 +97,22 @@ test('providerGitHub implements delete method', async () => {
9797
global.fetch = vi.fn((url, options) => {
9898
if (
9999
url ===
100-
'https://api.github.com/repos/callstackincubator/rock/actions/artifacts?per_page=100&page=1&name=rock-android-debug-1234567890'
100+
'https://api.github.com/repos/callstack/rock/actions/artifacts?per_page=100&page=1&name=rock-android-debug-1234567890'
101101
) {
102102
return Promise.resolve(
103103
new Response(JSON.stringify({ artifacts: ARTIFACTS })),
104104
);
105105
}
106106
if (
107107
url ===
108-
'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/123' &&
108+
'https://api.github.com/repos/callstack/rock/actions/artifacts/123' &&
109109
options.method === 'DELETE'
110110
) {
111111
return Promise.resolve(new Response());
112112
}
113113
if (
114114
url ===
115-
'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/124' &&
115+
'https://api.github.com/repos/callstack/rock/actions/artifacts/124' &&
116116
options.method === 'DELETE'
117117
) {
118118
return Promise.resolve(new Response());
@@ -131,11 +131,11 @@ test('providerGitHub implements delete method', async () => {
131131
expect(response).toEqual([
132132
{
133133
name: 'rock-android-debug-1234567890',
134-
url: 'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/123',
134+
url: 'https://api.github.com/repos/callstack/rock/actions/artifacts/123',
135135
},
136136
{
137137
name: 'rock-android-debug-1234567890',
138-
url: 'https://api.github.com/repos/callstackincubator/rock/actions/artifacts/124',
138+
url: 'https://api.github.com/repos/callstack/rock/actions/artifacts/124',
139139
},
140140
]);
141141
});

scripts/npm-publish.sh

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,60 @@
11
#!/bin/bash
2-
set -e
2+
set -euo pipefail
3+
4+
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
35

46
echo "Building all packages..."
57

68
pnpm build
79

8-
if [ -z "$NPM_TOKEN" ] && [ -z "$CI" ] && [ -z "$GITHUB_ACTIONS" ]; then
10+
if [ -z "${CI:-}" ] && [ -z "${GITHUB_ACTIONS:-}" ]; then
911
read -p "Enter NPM OTP: " OTP
1012
fi
1113

14+
publish_package() {
15+
local package_dir="$1"
16+
local package_json="$package_dir/package.json"
17+
shift
18+
19+
local package_name
20+
local package_version
21+
local package_ref
22+
23+
package_name=$(node -p "require(process.argv[1]).name" "$package_json")
24+
package_version=$(node -p "require(process.argv[1]).version" "$package_json")
25+
package_ref="${package_name}@${package_version}"
26+
27+
if npm view "$package_ref" version --registry https://registry.npmjs.org/ --silent >/dev/null 2>&1; then
28+
echo "Skipping already published package ${package_ref}"
29+
return 0
30+
fi
31+
32+
echo "Publishing ${package_ref}"
33+
(
34+
cd "$package_dir"
35+
npm publish "$@"
36+
)
37+
}
38+
1239
echo "NPM: Publishing all packages"
13-
# In CI, trusted publishing should be non-interactive and not require OTP input.
14-
if [ -n "$NPM_TOKEN" ] || [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ]; then
15-
pnpm -r run publish:npm
16-
else
17-
pnpm -r --no-bail run publish:npm --otp="$OTP"
18-
fi
40+
for package_json in "$ROOT_DIR"/packages/*/package.json; do
41+
if ! grep -q '"publish:npm"' "$package_json"; then
42+
continue
43+
fi
44+
45+
publish_args=()
46+
if [ -z "${CI:-}" ] && [ -z "${GITHUB_ACTIONS:-}" ]; then
47+
publish_args+=(--otp="$OTP")
48+
fi
49+
50+
publish_package "${package_json%/package.json}" --access public "${publish_args[@]}"
51+
done
1952

2053
echo "NPM: Publishing template"
21-
cd templates/rock-template-default
22-
# In CI, trusted publishing should be non-interactive and not require OTP input.
23-
if [ -n "$NPM_TOKEN" ] || [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ]; then
24-
npm publish
25-
else
26-
npm publish --otp="$OTP"
54+
template_publish_args=()
55+
if [ -z "${CI:-}" ] && [ -z "${GITHUB_ACTIONS:-}" ]; then
56+
template_publish_args+=(--otp="$OTP")
2757
fi
58+
publish_package "$ROOT_DIR/templates/rock-template-default" --access public "${template_publish_args[@]}"
2859

2960
echo "Done"

0 commit comments

Comments
 (0)