| name: Release |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| on: |
| push: |
| tags: ['v*'] |
| workflow_dispatch: |
| inputs: |
| tag: |
| description: 'Tag to release (e.g. v0.2.0). Leave empty for dry-run from ref.' |
| required: false |
| ref: |
| description: 'Git ref for dry-run testing (branch, tag, or SHA). Defaults to main.' |
| required: false |
| default: 'main' |
| dry_run: |
| description: 'Build release artifacts without publishing them.' |
| required: false |
| type: boolean |
| default: false |
|
|
| env: |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true |
| GORELEASER_VERSION: v2.14.3 |
|
|
| permissions: |
| contents: write |
|
|
| jobs: |
| release: |
| name: Release Binaries |
| runs-on: ubuntu-latest |
| permissions: |
| contents: write |
| steps: |
| - name: Validate workflow inputs |
| if: ${{ github.event_name == 'workflow_dispatch' }} |
| run: | |
| if [ "${{ inputs.dry_run }}" != "true" ] && [ -z "${{ github.event.inputs.tag }}" ]; then |
| echo "tag is required unless dry_run=true" >&2 |
| exit 1 |
| fi |
| |
| - uses: actions/checkout@v5 |
| with: |
| fetch-depth: 0 |
| ref: ${{ github.event.inputs.tag || github.event.inputs.ref || github.ref }} |
|
|
| - uses: actions/setup-go@v6 |
| with: |
| go-version: '1.26' |
|
|
| - uses: oven-sh/setup-bun@v2 |
| with: |
| bun-version: latest |
|
|
| - name: Install dashboard dependencies |
| working-directory: dashboard |
| run: bun install --frozen-lockfile |
|
|
| - name: Run GoReleaser |
| run: | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.dry_run }}" = "true" ]; then |
| ARGS="release --clean --snapshot" |
| else |
| ARGS="release --clean" |
| fi |
| |
| curl -sfL https://goreleaser.com/static/run | VERSION="$GORELEASER_VERSION" bash -s -- $ARGS |
| env: |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} |
|
|
| npm: |
| name: Publish to npm |
| runs-on: ubuntu-latest |
| needs: release |
| permissions: |
| contents: read |
| steps: |
| - uses: actions/checkout@v5 |
| with: |
| ref: ${{ github.event.inputs.tag || github.event.inputs.ref || github.ref }} |
|
|
| - uses: actions/setup-node@v5 |
| with: |
| node-version: '22' |
| registry-url: 'https://registry.npmjs.org' |
|
|
| - name: Extract version |
| id: version |
| run: | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.dry_run }}" = "true" ] && [ -z "${{ github.event.inputs.tag }}" ]; then |
| VERSION=$(jq -r .version npm/package.json) |
| else |
| TAG="${{ github.event.inputs.tag || github.ref_name }}" |
| VERSION=${TAG#v} # Remove 'v' prefix |
| fi |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" |
| |
| - name: Update npm package version |
| if: ${{ github.event_name != 'workflow_dispatch' || !inputs.dry_run }} |
| working-directory: npm |
| run: | |
| CURRENT=$(jq -r .version package.json) |
| DESIRED=${{ steps.version.outputs.version }} |
| if [ "$CURRENT" != "$DESIRED" ]; then |
| npm version "$DESIRED" --no-git-tag-version |
| else |
| echo "Version already correct: $CURRENT" |
| fi |
| |
| - name: Install dependencies |
| working-directory: npm |
| run: npm ci --ignore-scripts |
|
|
| - name: Build TypeScript |
| working-directory: npm |
| run: npm run build |
|
|
| - name: Dry-run npm publish |
| if: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run }} |
| working-directory: npm |
| run: npm publish --dry-run |
| env: |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
|
|
| - name: Publish to npm |
| if: ${{ github.event_name != 'workflow_dispatch' || !inputs.dry_run }} |
| working-directory: npm |
| run: npm publish |
| env: |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
|
|
| docker: |
| name: Docker Image |
| runs-on: ubuntu-latest |
| needs: release |
| permissions: |
| contents: read |
| packages: write |
| steps: |
| - uses: actions/checkout@v5 |
| with: |
| ref: ${{ github.event.inputs.tag || github.event.inputs.ref || github.ref }} |
|
|
| - name: Extract Docker metadata |
| id: meta |
| run: | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.dry_run }}" = "true" ]; then |
| if [ -n "${{ github.event.inputs.tag }}" ]; then |
| TAG="${{ github.event.inputs.tag }}" |
| VERSION="${TAG#v}-dryrun-${GITHUB_SHA::7}" |
| else |
| TAG="dry-run-${GITHUB_SHA::7}" |
| VERSION="$(jq -r .version npm/package.json)-dryrun-${GITHUB_SHA::7}" |
| fi |
| PUSH="false" |
| else |
| TAG="${{ github.event.inputs.tag || github.ref_name }}" |
| VERSION="${TAG#v}" |
| PUSH="true" |
| fi |
| |
| { |
| echo "tag=$TAG" |
| echo "version=$VERSION" |
| echo "push=$PUSH" |
| } >> "$GITHUB_OUTPUT" |
|
|
| - name: Docker dry-run note |
| if: ${{ steps.meta.outputs.push != 'true' }} |
| run: | |
| echo "Running a multi-arch Docker build without pushing to GHCR or Docker Hub." >> "$GITHUB_STEP_SUMMARY" |
| |
| - uses: docker/setup-qemu-action@v3 |
| - uses: docker/setup-buildx-action@v3 |
|
|
| - uses: docker/login-action@v3 |
| if: ${{ steps.meta.outputs.push == 'true' }} |
| with: |
| username: ${{ secrets.DOCKERHUB_USER }} |
| password: ${{ secrets.DOCKERHUB_TOKEN }} |
|
|
| - uses: docker/login-action@v3 |
| if: ${{ steps.meta.outputs.push == 'true' }} |
| with: |
| registry: ghcr.io |
| username: ${{ github.actor }} |
| password: ${{ secrets.GITHUB_TOKEN }} |
|
|
| - uses: docker/build-push-action@v6 |
| with: |
| context: . |
| file: ./Dockerfile |
| platforms: linux/amd64,linux/arm64 |
| push: ${{ steps.meta.outputs.push == 'true' }} |
| provenance: false |
| labels: | |
| org.opencontainers.image.source=https://github.com/pinchtab/pinchtab |
| org.opencontainers.image.version=${{ steps.meta.outputs.version }} |
| tags: | |
| ghcr.io/pinchtab/pinchtab:latest |
| ghcr.io/pinchtab/pinchtab:${{ steps.meta.outputs.tag }} |
| ghcr.io/pinchtab/pinchtab:${{ steps.meta.outputs.version }} |
| pinchtab/pinchtab:latest |
| pinchtab/pinchtab:${{ steps.meta.outputs.tag }} |
| pinchtab/pinchtab:${{ steps.meta.outputs.version }} |
| |
| skill: |
| name: Publish Skill |
| needs: |
| - npm |
| - docker |
| if: ${{ github.event_name != 'workflow_dispatch' || !inputs.dry_run }} |
| uses: ./.github/workflows/publish-skill.yml |
| with: |
| version: ${{ github.event.inputs.tag || github.ref_name }} |
| secrets: |
| CLAWHUB_TOKEN: ${{ secrets.CLAWHUB_TOKEN }} |
|
|