fix: 强化 team task-board 稳定性 #17
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish to npm | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Tag to publish, for example v0.1.1 or v0.1.2-beta.1" | |
| required: true | |
| concurrency: | |
| group: publish-${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }} | |
| cancel-in-progress: false | |
| jobs: | |
| prepare: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag: ${{ steps.ref.outputs.tag }} | |
| version: ${{ steps.tag.outputs.version }} | |
| base_version: ${{ steps.tag.outputs.base_version }} | |
| channel: ${{ steps.tag.outputs.channel }} | |
| is_beta: ${{ steps.tag.outputs.is_beta }} | |
| npm_version: ${{ steps.tag.outputs.npm_version }} | |
| steps: | |
| - name: Resolve tag ref | |
| id: ref | |
| shell: bash | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Checkout tag | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ steps.ref.outputs.tag }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| - name: Ensure npm 11 | |
| run: npm install -g npm@11 && npm --version | |
| - name: Parse tag | |
| id: tag | |
| shell: bash | |
| run: | | |
| TAG="${{ steps.ref.outputs.tag }}" | |
| VERSION="${TAG#v}" | |
| if [[ "$VERSION" =~ ^([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "base_version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "channel=latest" >> "$GITHUB_OUTPUT" | |
| echo "is_beta=false" >> "$GITHUB_OUTPUT" | |
| echo "npm_version=$VERSION" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [[ "$VERSION" =~ ^([0-9]+\.[0-9]+\.[0-9]+)-beta\.([0-9]+)$ ]]; then | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "base_version=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT" | |
| echo "channel=beta" >> "$GITHUB_OUTPUT" | |
| echo "is_beta=true" >> "$GITHUB_OUTPUT" | |
| echo "npm_version=$VERSION" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "::error::Unsupported tag format: $TAG" | |
| echo "::error::Use vX.Y.Z or vX.Y.Z-beta.N" | |
| exit 1 | |
| - name: Verify package version | |
| shell: bash | |
| run: | | |
| PKG_VERSION=$(node -p "require('./package.json').version") | |
| if [ "$PKG_VERSION" != "${{ steps.tag.outputs.base_version }}" ]; then | |
| echo "::error::package.json version ($PKG_VERSION) does not match tag base version (${{ steps.tag.outputs.base_version }})" | |
| exit 1 | |
| fi | |
| - name: Verify plugin manifest version | |
| shell: bash | |
| run: | | |
| PLUGIN_VERSION=$(node -p "require('./.claude-plugin/plugin.json').version") | |
| if [ "$PLUGIN_VERSION" != "${{ steps.tag.outputs.base_version }}" ]; then | |
| echo "::error::.claude-plugin/plugin.json version ($PLUGIN_VERSION) does not match tag base version (${{ steps.tag.outputs.base_version }})" | |
| exit 1 | |
| fi | |
| - name: Verify repository URL | |
| shell: bash | |
| run: | | |
| REPO_URL=$(node -p "const pkg=require('./package.json'); const repo=pkg.repository; typeof repo === 'string' ? repo : (repo && repo.url) || ''") | |
| EXPECTED_URL="https://github.com/${{ github.repository }}.git" | |
| EXPECTED_GIT_URL="git+${EXPECTED_URL}" | |
| if [ "$REPO_URL" != "$EXPECTED_URL" ] && [ "$REPO_URL" != "$EXPECTED_GIT_URL" ]; then | |
| echo "::error::package.json repository.url ($REPO_URL) must equal $EXPECTED_URL or $EXPECTED_GIT_URL" | |
| exit 1 | |
| fi | |
| - name: Write summary | |
| shell: bash | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| { | |
| echo "### Publish Info" | |
| echo "" | |
| echo "| Field | Value |" | |
| echo "| --- | --- |" | |
| echo "| Tag | ${{ steps.ref.outputs.tag }} |" | |
| echo "| npm version | ${{ steps.tag.outputs.npm_version }} |" | |
| echo "| Channel | ${{ steps.tag.outputs.channel }} |" | |
| echo "| Beta | ${{ steps.tag.outputs.is_beta }} |" | |
| if [ -n "$NODE_AUTH_TOKEN" ]; then | |
| echo "| Auth mode | NPM_TOKEN |" | |
| else | |
| echo "| Auth mode | Trusted publishing (OIDC) |" | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| publish: | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| steps: | |
| - name: Checkout tag | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ needs.prepare.outputs.tag }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| - name: Ensure npm 11 | |
| run: npm install -g npm@11 && npm --version | |
| - name: Set beta version in package.json | |
| if: needs.prepare.outputs.is_beta == 'true' | |
| run: npm version "${{ needs.prepare.outputs.npm_version }}" --no-git-tag-version | |
| - name: Set beta version in plugin manifest | |
| if: needs.prepare.outputs.is_beta == 'true' | |
| shell: bash | |
| run: | | |
| node -e "const fs=require('fs'); const file='./.claude-plugin/plugin.json'; const data=JSON.parse(fs.readFileSync(file, 'utf8')); data.version=process.argv[1]; fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n', 'utf8');" "${{ needs.prepare.outputs.npm_version }}" | |
| - name: Run checks | |
| run: npm run check | |
| - name: Preview package contents | |
| run: npm pack --dry-run | |
| - name: Publish with NPM token | |
| if: env.NODE_AUTH_TOKEN != '' | |
| run: npm publish --access public --tag ${{ needs.prepare.outputs.channel }} | |
| - name: Publish with trusted publishing | |
| if: env.NODE_AUTH_TOKEN == '' | |
| run: npm publish --access public --tag ${{ needs.prepare.outputs.channel }} | |
| release: | |
| needs: [prepare, publish] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| issues: read | |
| pull-requests: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create or update GitHub Release | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| GITHUB_TOKEN: ${{ github.token }} | |
| REPOSITORY: ${{ github.repository }} | |
| TAG_NAME: ${{ needs.prepare.outputs.tag }} | |
| RELEASE_TITLE: ${{ needs.prepare.outputs.version }} | |
| IS_PRERELEASE: ${{ needs.prepare.outputs.is_beta }} | |
| run: | | |
| set -euo pipefail | |
| notes_file="$(mktemp)" | |
| node ./scripts/generate-release-notes.mjs \ | |
| --repo "$REPOSITORY" \ | |
| --tag "$TAG_NAME" \ | |
| --output "$notes_file" | |
| prerelease_args=() | |
| if [ "$IS_PRERELEASE" = "true" ]; then | |
| prerelease_args+=(--prerelease) | |
| fi | |
| if gh release view "$TAG_NAME" --repo "$REPOSITORY" >/dev/null 2>&1; then | |
| gh release edit "$TAG_NAME" \ | |
| --repo "$REPOSITORY" \ | |
| --title "$RELEASE_TITLE" \ | |
| --notes-file "$notes_file" \ | |
| "${prerelease_args[@]}" | |
| else | |
| gh release create "$TAG_NAME" \ | |
| --repo "$REPOSITORY" \ | |
| --title "$RELEASE_TITLE" \ | |
| --notes-file "$notes_file" \ | |
| --verify-tag \ | |
| "${prerelease_args[@]}" | |
| fi |