Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ on:
branches:
- main

permissions:
contents: write
id-token: write

jobs:
build:
strategy:
Expand Down Expand Up @@ -47,5 +51,44 @@ jobs:
name: ${{ matrix.settings.artifact }}
path: target

- name: Publish
run: pnpm changeset publish
publish:
name: Publish to npm
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 25.9.0
registry-url: 'https://registry.npmjs.org'

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 10.33.0
run_install: true

- name: Publish packages
id: changesets
uses: changesets/action@v1
with:
publish: pnpm exec changeset publish
createGithubReleases: true
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Download build artifacts
if: steps.changesets.outputs.published == 'true'
uses: actions/download-artifact@v6
with:
path: artifacts

- name: Upload executable archives to release
if: steps.changesets.outputs.published == 'true'
run: node scripts/upload-release-assets.ts
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PUBLISHED_PACKAGES: ${{ steps.changesets.outputs.publishedPackages }}
63 changes: 63 additions & 0 deletions scripts/upload-release-assets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { spawn } from 'node:child_process'
import { readdir } from 'node:fs/promises'
import { join, resolve } from 'node:path'
import process from 'node:process'

type RunOptions = Parameters<typeof spawn>[2]

interface PublishedPackage {
name: string
version: string
}

function run(command: string, args: string[], options: RunOptions = {}) {
return new Promise<void>((resolvePromise, rejectPromise) => {
const child = spawn(command, args, { stdio: 'inherit', ...options })
child.on('error', rejectPromise)
child.on('close', (code) => {
if (code === 0) {
resolvePromise()
return
}
rejectPromise(new Error(`Command failed: ${command} ${args.join(' ')}`))
})
})
}

function resolveReleaseMeta() {
const raw = process.env.PUBLISHED_PACKAGES ?? '[]'
const publishedPackages = JSON.parse(raw) as PublishedPackage[]
if (!Array.isArray(publishedPackages) || publishedPackages.length === 0) {
throw new Error('No published packages returned by changesets/action')
}
const pkg = publishedPackages.find(item => item.name === '@arkts/mcp') ?? publishedPackages[0]
const version = pkg.version
const tagName = `${pkg.name}@${pkg.version}`
return { version, tagName }
}

async function main() {
const artifactsDir = resolve(process.env.ARTIFACTS_DIR ?? 'artifacts')
const releaseAssetsDir = resolve(process.env.RELEASE_ASSETS_DIR ?? 'release-assets')
const { version, tagName } = resolveReleaseMeta()

await run('mkdir', ['-p', releaseAssetsDir])

const entries = await readdir(artifactsDir, { withFileTypes: true })
const artifactDirs = entries.filter(entry => entry.isDirectory()).map(entry => entry.name)
if (artifactDirs.length === 0) {
throw new Error(`No artifact directories found in ${artifactsDir}`)
}

for (const artifactName of artifactDirs) {
const artifactPath = join(artifactsDir, artifactName)
const zipPath = join(releaseAssetsDir, `${artifactName}-${version}.zip`)
await run('zip', ['-r', zipPath, '.'], { cwd: artifactPath })
}

await run('gh', ['release', 'upload', tagName, `${releaseAssetsDir}/*.zip`, '--clobber'], {
shell: true,
})
}

await main()
Loading