refactor(ci): separate platform publish into dedicated workflow
- publish.yml: main package only, triggers platform workflow on success - publish-platform.yml: dedicated workflow with fresh OIDC token per run - Fixes OIDC token expiration during large binary uploads (~40MB+) - Platform workflow can also be triggered manually via workflow_dispatch
This commit is contained in:
parent
89bde5ce64
commit
7f2eb0a568
108
.github/workflows/publish-platform.yml
vendored
Normal file
108
.github/workflows/publish-platform.yml
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
name: publish-platform
|
||||||
|
run-name: "platform packages ${{ inputs.version }}"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
dist_tag:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Version to publish (e.g., 3.0.0-beta.12)"
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
dist_tag:
|
||||||
|
description: "npm dist tag (e.g., beta, latest)"
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-platform:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 2
|
||||||
|
matrix:
|
||||||
|
platform: [darwin-arm64, darwin-x64, linux-x64, linux-arm64, linux-x64-musl, linux-arm64-musl, windows-x64]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: oven-sh/setup-bun@v2
|
||||||
|
with:
|
||||||
|
bun-version: latest
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "24"
|
||||||
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bun install
|
||||||
|
env:
|
||||||
|
BUN_INSTALL_ALLOW_SCRIPTS: "@ast-grep/napi"
|
||||||
|
|
||||||
|
- name: Check if already published
|
||||||
|
id: check
|
||||||
|
run: |
|
||||||
|
PKG_NAME="oh-my-opencode-${{ matrix.platform }}"
|
||||||
|
VERSION="${{ inputs.version }}"
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/${PKG_NAME}/${VERSION}")
|
||||||
|
if [ "$STATUS" = "200" ]; then
|
||||||
|
echo "skip=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✓ ${PKG_NAME}@${VERSION} already published"
|
||||||
|
else
|
||||||
|
echo "skip=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "→ ${PKG_NAME}@${VERSION} needs publishing"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Update version
|
||||||
|
if: steps.check.outputs.skip != 'true'
|
||||||
|
run: |
|
||||||
|
VERSION="${{ inputs.version }}"
|
||||||
|
cd packages/${{ matrix.platform }}
|
||||||
|
jq --arg v "$VERSION" '.version = $v' package.json > tmp.json && mv tmp.json package.json
|
||||||
|
|
||||||
|
- name: Build binary
|
||||||
|
if: steps.check.outputs.skip != 'true'
|
||||||
|
run: |
|
||||||
|
PLATFORM="${{ matrix.platform }}"
|
||||||
|
case "$PLATFORM" in
|
||||||
|
darwin-arm64) TARGET="bun-darwin-arm64" ;;
|
||||||
|
darwin-x64) TARGET="bun-darwin-x64" ;;
|
||||||
|
linux-x64) TARGET="bun-linux-x64" ;;
|
||||||
|
linux-arm64) TARGET="bun-linux-arm64" ;;
|
||||||
|
linux-x64-musl) TARGET="bun-linux-x64-musl" ;;
|
||||||
|
linux-arm64-musl) TARGET="bun-linux-arm64-musl" ;;
|
||||||
|
windows-x64) TARGET="bun-windows-x64" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$PLATFORM" = "windows-x64" ]; then
|
||||||
|
OUTPUT="packages/${PLATFORM}/bin/oh-my-opencode.exe"
|
||||||
|
else
|
||||||
|
OUTPUT="packages/${PLATFORM}/bin/oh-my-opencode"
|
||||||
|
fi
|
||||||
|
|
||||||
|
bun build src/cli/index.ts --compile --minify --target=$TARGET --outfile=$OUTPUT
|
||||||
|
|
||||||
|
- name: Publish ${{ matrix.platform }}
|
||||||
|
if: steps.check.outputs.skip != 'true'
|
||||||
|
run: |
|
||||||
|
cd packages/${{ matrix.platform }}
|
||||||
|
TAG_ARG=""
|
||||||
|
if [ -n "${{ inputs.dist_tag }}" ]; then
|
||||||
|
TAG_ARG="--tag ${{ inputs.dist_tag }}"
|
||||||
|
fi
|
||||||
|
npm publish --access public $TAG_ARG
|
||||||
|
env:
|
||||||
|
NPM_CONFIG_PROVENANCE: false
|
||||||
187
.github/workflows/publish.yml
vendored
187
.github/workflows/publish.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
name: publish
|
name: publish
|
||||||
run-name: "${{ format('release {0}', inputs.bump) }}"
|
run-name: "${{ format('release {0}', inputs.version || inputs.bump) }}"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@ -14,16 +14,11 @@ on:
|
|||||||
- minor
|
- minor
|
||||||
- major
|
- major
|
||||||
version:
|
version:
|
||||||
description: "Override version (e.g., 3.0.0-beta.6 for beta release). Takes precedence over bump."
|
description: "Override version (e.g., 3.0.0-beta.6). Takes precedence over bump."
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
skip_platform:
|
skip_platform:
|
||||||
description: "Skip platform binary packages (use when already published)"
|
description: "Skip platform binary packages"
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
republish:
|
|
||||||
description: "Re-publish mode: skip version check, only publish missing packages"
|
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
@ -33,6 +28,7 @@ concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
id-token: write
|
id-token: write
|
||||||
|
actions: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
@ -69,8 +65,7 @@ jobs:
|
|||||||
- name: Type check
|
- name: Type check
|
||||||
run: bun run typecheck
|
run: bun run typecheck
|
||||||
|
|
||||||
# Build everything and upload artifacts
|
publish-main:
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [test, typecheck]
|
needs: [test, typecheck]
|
||||||
if: github.repository == 'code-yeongyu/oh-my-opencode'
|
if: github.repository == 'code-yeongyu/oh-my-opencode'
|
||||||
@ -88,6 +83,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
bun-version: latest
|
bun-version: latest
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "24"
|
||||||
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: bun install
|
run: bun install
|
||||||
env:
|
env:
|
||||||
@ -109,7 +109,6 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
# Calculate dist tag
|
|
||||||
if [[ "$VERSION" == *"-"* ]]; then
|
if [[ "$VERSION" == *"-"* ]]; then
|
||||||
DIST_TAG=$(echo "$VERSION" | cut -d'-' -f2 | cut -d'.' -f1)
|
DIST_TAG=$(echo "$VERSION" | cut -d'-' -f2 | cut -d'.' -f1)
|
||||||
echo "dist_tag=${DIST_TAG:-next}" >> $GITHUB_OUTPUT
|
echo "dist_tag=${DIST_TAG:-next}" >> $GITHUB_OUTPUT
|
||||||
@ -119,43 +118,52 @@ jobs:
|
|||||||
|
|
||||||
echo "Version: $VERSION"
|
echo "Version: $VERSION"
|
||||||
|
|
||||||
- name: Update versions in package.json files
|
- name: Check if already published
|
||||||
run: bun run script/publish.ts --prepare-only
|
id: check
|
||||||
env:
|
run: |
|
||||||
VERSION: ${{ steps.version.outputs.version }}
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/oh-my-opencode/${VERSION}")
|
||||||
|
if [ "$STATUS" = "200" ]; then
|
||||||
|
echo "skip=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✓ oh-my-opencode@${VERSION} already published"
|
||||||
|
else
|
||||||
|
echo "skip=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Update version
|
||||||
|
if: steps.check.outputs.skip != 'true'
|
||||||
|
run: |
|
||||||
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
jq --arg v "$VERSION" '.version = $v' package.json > tmp.json && mv tmp.json package.json
|
||||||
|
|
||||||
|
for platform in darwin-arm64 darwin-x64 linux-x64 linux-arm64 linux-x64-musl linux-arm64-musl windows-x64; do
|
||||||
|
jq --arg v "$VERSION" '.version = $v' "packages/${platform}/package.json" > tmp.json
|
||||||
|
mv tmp.json "packages/${platform}/package.json"
|
||||||
|
done
|
||||||
|
|
||||||
|
jq --arg v "$VERSION" '.optionalDependencies = (.optionalDependencies | to_entries | map(.value = $v) | from_entries)' package.json > tmp.json && mv tmp.json package.json
|
||||||
|
|
||||||
- name: Build main package
|
- name: Build main package
|
||||||
|
if: steps.check.outputs.skip != 'true'
|
||||||
run: |
|
run: |
|
||||||
bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi
|
bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi
|
||||||
bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi
|
bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi
|
||||||
bunx tsc --emitDeclarationOnly
|
bunx tsc --emitDeclarationOnly
|
||||||
bun run build:schema
|
bun run build:schema
|
||||||
|
|
||||||
- name: Build platform binaries
|
- name: Publish main package
|
||||||
if: inputs.skip_platform != true
|
if: steps.check.outputs.skip != 'true'
|
||||||
run: bun run build:binaries
|
run: |
|
||||||
|
TAG_ARG=""
|
||||||
- name: Upload main package artifact
|
if [ -n "${{ steps.version.outputs.dist_tag }}" ]; then
|
||||||
uses: actions/upload-artifact@v4
|
TAG_ARG="--tag ${{ steps.version.outputs.dist_tag }}"
|
||||||
with:
|
fi
|
||||||
name: main-package
|
npm publish --access public --provenance $TAG_ARG
|
||||||
path: |
|
env:
|
||||||
dist/
|
NPM_CONFIG_PROVENANCE: true
|
||||||
package.json
|
|
||||||
assets/
|
|
||||||
README.md
|
|
||||||
LICENSE.md
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
- name: Upload platform artifacts
|
|
||||||
if: inputs.skip_platform != true
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: platform-packages
|
|
||||||
path: packages/
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
- name: Git commit and tag
|
- name: Git commit and tag
|
||||||
|
if: steps.check.outputs.skip != 'true'
|
||||||
run: |
|
run: |
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
@ -167,98 +175,24 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
# Publish platform packages in parallel (each job gets fresh OIDC token)
|
trigger-platform:
|
||||||
publish-platform:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: publish-main
|
||||||
if: inputs.skip_platform != true
|
if: inputs.skip_platform != true
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform: [darwin-arm64, darwin-x64, linux-x64, linux-arm64, linux-x64-musl, linux-arm64-musl, windows-x64]
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-node@v4
|
- name: Trigger platform publish workflow
|
||||||
with:
|
|
||||||
node-version: "24"
|
|
||||||
registry-url: "https://registry.npmjs.org"
|
|
||||||
|
|
||||||
- name: Download platform artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: platform-packages
|
|
||||||
path: packages/
|
|
||||||
|
|
||||||
- name: Check if already published
|
|
||||||
id: check
|
|
||||||
run: |
|
run: |
|
||||||
PKG_NAME="oh-my-opencode-${{ matrix.platform }}"
|
gh workflow run publish-platform.yml \
|
||||||
VERSION="${{ needs.build.outputs.version }}"
|
--repo ${{ github.repository }} \
|
||||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/${PKG_NAME}/${VERSION}")
|
--ref ${{ github.ref }} \
|
||||||
if [ "$STATUS" = "200" ]; then
|
-f version=${{ needs.publish-main.outputs.version }} \
|
||||||
echo "skip=true" >> $GITHUB_OUTPUT
|
-f dist_tag=${{ needs.publish-main.outputs.dist_tag }}
|
||||||
echo "✓ ${PKG_NAME}@${VERSION} already published"
|
|
||||||
else
|
|
||||||
echo "skip=false" >> $GITHUB_OUTPUT
|
|
||||||
echo "→ ${PKG_NAME}@${VERSION} needs publishing"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Publish ${{ matrix.platform }}
|
|
||||||
if: steps.check.outputs.skip != 'true'
|
|
||||||
run: |
|
|
||||||
cd packages/${{ matrix.platform }}
|
|
||||||
TAG_ARG=""
|
|
||||||
if [ -n "${{ needs.build.outputs.dist_tag }}" ]; then
|
|
||||||
TAG_ARG="--tag ${{ needs.build.outputs.dist_tag }}"
|
|
||||||
fi
|
|
||||||
npm publish --access public $TAG_ARG
|
|
||||||
env:
|
env:
|
||||||
NPM_CONFIG_PROVENANCE: false
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
# Publish main package after all platform packages
|
|
||||||
publish-main:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [build, publish-platform]
|
|
||||||
if: always() && needs.build.result == 'success' && (inputs.skip_platform == true || needs.publish-platform.result == 'success' || needs.publish-platform.result == 'skipped')
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: "24"
|
|
||||||
registry-url: "https://registry.npmjs.org"
|
|
||||||
|
|
||||||
- name: Download main package artifact
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: main-package
|
|
||||||
path: .
|
|
||||||
|
|
||||||
- name: Check if already published
|
|
||||||
id: check
|
|
||||||
run: |
|
|
||||||
VERSION="${{ needs.build.outputs.version }}"
|
|
||||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/oh-my-opencode/${VERSION}")
|
|
||||||
if [ "$STATUS" = "200" ]; then
|
|
||||||
echo "skip=true" >> $GITHUB_OUTPUT
|
|
||||||
echo "✓ oh-my-opencode@${VERSION} already published"
|
|
||||||
else
|
|
||||||
echo "skip=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Publish main package
|
|
||||||
if: steps.check.outputs.skip != 'true'
|
|
||||||
run: |
|
|
||||||
TAG_ARG=""
|
|
||||||
if [ -n "${{ needs.build.outputs.dist_tag }}" ]; then
|
|
||||||
TAG_ARG="--tag ${{ needs.build.outputs.dist_tag }}"
|
|
||||||
fi
|
|
||||||
npm publish --access public --provenance $TAG_ARG
|
|
||||||
env:
|
|
||||||
NPM_CONFIG_PROVENANCE: true
|
|
||||||
|
|
||||||
# Create release and cleanup
|
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build, publish-main]
|
needs: publish-main
|
||||||
if: always() && needs.build.result == 'success'
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -267,9 +201,8 @@ jobs:
|
|||||||
- name: Generate changelog
|
- name: Generate changelog
|
||||||
id: changelog
|
id: changelog
|
||||||
run: |
|
run: |
|
||||||
VERSION="${{ needs.build.outputs.version }}"
|
VERSION="${{ needs.publish-main.outputs.version }}"
|
||||||
|
|
||||||
# Find previous tag
|
|
||||||
PREV_TAG=""
|
PREV_TAG=""
|
||||||
if [[ "$VERSION" == *"-beta."* ]]; then
|
if [[ "$VERSION" == *"-beta."* ]]; then
|
||||||
BASE="${VERSION%-beta.*}"
|
BASE="${VERSION%-beta.*}"
|
||||||
@ -289,13 +222,11 @@ jobs:
|
|||||||
|
|
||||||
NOTES=$(git log "v${PREV_TAG}..v${VERSION}" --oneline --format="- %h %s" 2>/dev/null | grep -vE "^- \w+ (ignore:|test:|chore:|ci:|release:)" || echo "No notable changes")
|
NOTES=$(git log "v${PREV_TAG}..v${VERSION}" --oneline --format="- %h %s" 2>/dev/null | grep -vE "^- \w+ (ignore:|test:|chore:|ci:|release:)" || echo "No notable changes")
|
||||||
|
|
||||||
# Write to file for multiline support
|
|
||||||
echo "$NOTES" > /tmp/changelog.md
|
echo "$NOTES" > /tmp/changelog.md
|
||||||
echo "notes_file=/tmp/changelog.md" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Create GitHub release
|
- name: Create GitHub release
|
||||||
run: |
|
run: |
|
||||||
VERSION="${{ needs.build.outputs.version }}"
|
VERSION="${{ needs.publish-main.outputs.version }}"
|
||||||
gh release view "v${VERSION}" >/dev/null 2>&1 || \
|
gh release view "v${VERSION}" >/dev/null 2>&1 || \
|
||||||
gh release create "v${VERSION}" --title "v${VERSION}" --notes-file /tmp/changelog.md
|
gh release create "v${VERSION}" --title "v${VERSION}" --notes-file /tmp/changelog.md
|
||||||
env:
|
env:
|
||||||
@ -311,7 +242,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
VERSION="${{ needs.build.outputs.version }}"
|
VERSION="${{ needs.publish-main.outputs.version }}"
|
||||||
git stash --include-untracked || true
|
git stash --include-untracked || true
|
||||||
git checkout master
|
git checkout master
|
||||||
git reset --hard "v${VERSION}"
|
git reset --hard "v${VERSION}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user