Skip to content

Commit a2e21b3

Browse files
authored
Merge pull request #48 from OpenSourceAGI/claude/chat-agent-toolkit-ci-failures-c2qeql
fix(ci): make npm publish work in the bun workspace + add provenance …
2 parents 257239a + fac2d94 commit a2e21b3

9 files changed

Lines changed: 116 additions & 39 deletions

File tree

β€Ž.github/workflows/npm-publish.ymlβ€Ž

Lines changed: 75 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,26 @@ jobs:
2424

2525
- uses: oven-sh/setup-bun@v2
2626

27-
- name: Configure git
28-
run: |
29-
git config user.name "github-actions[bot]"
30-
git config user.email "github-actions[bot]@users.noreply.github.com"
31-
32-
- name: Publish changed non-private packages
27+
# Install the whole workspace once with bun (the repo's package manager).
28+
# bun understands the "workspace:*" protocol and links local packages, so
29+
# every package gets its devDependencies (e.g. vite) and can be built.
30+
# Plain `npm install` cannot do this inside a bun workspace β€” it dies on
31+
# sibling "workspace:*" deps (EUNSUPPORTEDPROTOCOL) and peer conflicts,
32+
# which left devDependencies uninstalled and builds failing with
33+
# "vite: not found".
34+
- name: Install workspace dependencies
35+
run: bun install
36+
37+
- name: Publish non-private packages with a new version
3338
env:
3439
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
3540
run: |
36-
set -euo pipefail
41+
# Note: intentionally no `-e`. Per-package outcomes are handled
42+
# explicitly so one package's failure can't abort the whole run.
43+
set -uo pipefail
3744
3845
failed_packages=""
46+
skipped_builds=""
3947
4048
for dir in packages/*/; do
4149
pkg="${dir}package.json"
@@ -47,66 +55,95 @@ jobs:
4755
4856
is_private=$(node -e "const p=require('./$pkg'); console.log(!!p.private)")
4957
name=$(node -e "const p=require('./$pkg'); console.log(p.name)")
50-
version=$(node -e "const p=require('./$pkg'); console.log(p.version)")
5158
5259
if [ "$is_private" = "true" ]; then
5360
echo "⏭ Skipping $name (private)"
5461
continue
5562
fi
5663
57-
if git diff --quiet HEAD^ HEAD -- "$dir"; then
58-
echo "⏭ Skipping $name (no changes)"
59-
continue
60-
fi
61-
62-
echo "πŸ“¦ Releasing $name from $dir"
64+
echo "πŸ“¦ Evaluating $name from $dir"
6365
66+
# Each package is handled in a subshell with its own `set -e` so a
67+
# failing step propagates to $rc without killing the outer loop.
6468
(
69+
set -e
6570
cd "$dir"
6671
67-
remote_version=$(npm view "$name" version 2>/dev/null || echo "")
72+
version=$(node -e "const p=require('./package.json'); console.log(p.version)")
6873
69-
if [ "$remote_version" = "$version" ]; then
70-
echo "πŸ”Ό Bumping $name because $version already exists on npm"
71-
npm version patch --no-git-tag-version
72-
version=$(node -e "const p=require('./package.json'); console.log(p.version)")
74+
# Publish based on the version, not on which files the triggering
75+
# commit touched: if this exact version is already on npm there is
76+
# nothing new to release; otherwise a version bump signals changes
77+
# since the last published release, so publish it.
78+
already=$(npm view "$name@$version" version 2>/dev/null || echo "")
79+
if [ -n "$already" ]; then
80+
echo "⏭ $name@$version already on npm β€” nothing new to release"
81+
exit 0
7382
fi
7483
75-
# Strip workspace:* dependencies before install and build
84+
# npm keeps the literal "workspace:*" protocol in the tarball, which
85+
# consumers cannot resolve. Replace each "workspace:*" with a real
86+
# semver range ("^<version>") taken from the referenced local
87+
# package so published packages keep depending on their siblings.
88+
# A local package that isn't published is dropped instead.
89+
# (This runs on the ephemeral CI checkout and is never committed.)
7690
node -e "
7791
const fs = require('fs');
78-
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
79-
for (const section of ['dependencies', 'devDependencies', 'peerDependencies']) {
80-
if (pkg[section]) {
81-
for (const [key, value] of Object.entries(pkg[section])) {
82-
if (typeof value === 'string' && value.startsWith('workspace:')) {
83-
delete pkg[section][key];
84-
console.log('Removed workspace dependency:', key);
85-
}
92+
const path = require('path');
93+
// Map local package name -> version across the workspace.
94+
const localVersions = {};
95+
for (const d of fs.readdirSync('..')) {
96+
const sib = path.join('..', d, 'package.json');
97+
if (!fs.existsSync(sib)) continue;
98+
try {
99+
const sp = JSON.parse(fs.readFileSync(sib, 'utf8'));
100+
if (sp.name && sp.version) localVersions[sp.name] = sp.version;
101+
} catch {}
102+
}
103+
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
104+
for (const s of ['dependencies', 'devDependencies', 'peerDependencies']) {
105+
if (!p[s]) continue;
106+
for (const [k, v] of Object.entries(p[s])) {
107+
if (typeof v !== 'string' || !v.startsWith('workspace:')) continue;
108+
if (localVersions[k]) {
109+
p[s][k] = '^' + localVersions[k];
110+
console.log('Pinned workspace dependency', k, '->', p[s][k]);
111+
} else {
112+
delete p[s][k];
113+
console.log('Removed unresolved workspace dependency:', k);
86114
}
87115
}
88116
}
89-
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
117+
fs.writeFileSync('package.json', JSON.stringify(p, null, 2));
90118
"
91119
92120
npm install --workspaces=false --ignore-scripts --legacy-peer-deps --include=dev
93121
94122
has_build=$(node -e "const p=require('./package.json'); console.log(!!(p.scripts && p.scripts.build))")
123+
build_ok=true
95124
if [ "$has_build" = "true" ]; then
96-
npm run build
125+
npm run build || build_ok=false
126+
fi
127+
128+
if [ "$build_ok" != "true" ]; then
129+
echo "⚠ Build failed for $name β€” not publishing (won't ship a broken tarball)"
130+
exit 42
97131
fi
98132
99-
echo "Publishing $(node -e "const p=require('./package.json'); console.log(p.name+'@'+p.version)")"
133+
echo "Publishing $name@$version"
100134
npm publish --provenance --access public
101-
) || {
102-
echo "❌ Failed to publish $name"
135+
)
136+
rc=$?
137+
138+
if [ "$rc" = "42" ]; then
139+
skipped_builds="$skipped_builds $name"
140+
elif [ "$rc" != "0" ]; then
103141
failed_packages="$failed_packages $name"
104-
}
142+
fi
105143
done
106144
107-
if [ -n "$failed_packages" ]; then
108-
echo "⚠ Failed packages:$failed_packages"
109-
exit 1
145+
if [ -n "$skipped_builds" ]; then
146+
echo "::warning::Skipped (build failed, not published):$skipped_builds"
110147
fi
111148
112149
- name: Commit version bumps
@@ -117,4 +154,4 @@ jobs:
117154
git add "${files[@]}"
118155
git diff --staged --quiet && echo "No version changes to commit" && exit 0
119156
git commit -m "chore: bump published package versions [skip ci]"
120-
git push
157+
git push

β€Žpackages/domain-rank/package.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
"name": "domain-rank",
33
"version": "0.1.2",
44
"description": "Domain Rank Top Million domains, source names, duplicates, and favicons",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
8+
"directory": "packages/domain-rank"
9+
},
510
"main": "./dist/index.cjs",
611
"module": "./dist/index.js",
712
"types": "./dist/index.d.ts",

β€Žpackages/extract-pdf-docling/package.jsonβ€Ž

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{
22
"name": "pdf-to-html-docling",
33
"version": "1.0.0",
4+
"repository": {
5+
"type": "git",
6+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
7+
"directory": "packages/extract-pdf-docling"
8+
},
49
"type": "module",
510
"scripts": {
611
"dev": "node --watch server.js",
@@ -14,4 +19,4 @@
1419
"hono": "^4.0.0",
1520
"zod": "^3.22.4"
1621
}
17-
}
22+
}

β€Žpackages/extract-webpage/package.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
"description": "Search, extract, cite, and outline the web for a topic with AI Research Agent.",
66
"author": "vtempest <grokthiscontact@gmail.com>",
77
"license": "rights.institute/PROSPER",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
11+
"directory": "packages/extract-webpage"
12+
},
813
"main": "./src/index.ts",
914
"types": "./src/types.d.ts",
1015
"exports": {

β€Žpackages/extract-youtube/package.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
],
5050
"author": "",
5151
"license": "MIT",
52+
"repository": {
53+
"type": "git",
54+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
55+
"directory": "packages/extract-youtube"
56+
},
5257
"dependencies": {
5358
"fast-xml-parser": "^4.2.5",
5459
"html-entities": "^2.3.3",

β€Žpackages/qwksearch-api-client/package.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
"name": "qwksearch-api-client",
33
"version": "0.0.13",
44
"description": "QwkSearch API Client - Generated from openapi-docs.yml",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
8+
"directory": "packages/qwksearch-api-client"
9+
},
510
"type": "module",
611
"main": "./dist/api-client.js",
712
"types": "./dist/index.d.ts",

β€Žpackages/reason-editor/package.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
"description": "Formatted Text Editor with toolbar for formatting, docs manager, and note outlines",
44
"version": "0.4.0",
55
"author": "vtempest",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
9+
"directory": "packages/reason-editor"
10+
},
611
"type": "module",
712
"main": "./dist/index.cjs",
813
"module": "./dist/index.mjs",

β€Žpackages/search-web-api/package.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
"version": "1.0.0",
66
"author": "vtempest",
77
"license": "MIT",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
11+
"directory": "packages/search-web-api"
12+
},
813
"scripts": {
914
"dev": "bun --watch demo/index.ts",
1015
"start": "bun demo/index.ts",

β€Žpackages/shadcn-app-dock/package.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
"description": "Prop-driven macOS-style category dock with magnification, a custom dropdown menu, and a built-in shadcn theme switcher",
44
"version": "0.1.0",
55
"author": "vtempest",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/OpenSourceAGI/qwksearch-research-agent",
9+
"directory": "packages/shadcn-app-dock"
10+
},
611
"type": "module",
712
"main": "./dist/index.cjs",
813
"module": "./dist/index.mjs",

0 commit comments

Comments
Β (0)