name: Release Web on: release: types: [released, prereleased] workflow_dispatch: inputs: ref: description: "Git ref (branch, tag, or SHA) to build" required: false default: "" tag_name: description: "Tag to use for artifacts/images (defaults to )" required: false default: "" attach_to_release: description: "Upload build.tar to an existing GitHub Release (requires tag_name)" required: false type: boolean default: false permissions: contents: write packages: write env: REGISTRY_IMAGE: ghcr.io/${{ github.repository }} jobs: release-web: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: ref: ${{ inputs.ref != '' && inputs.ref || github.ref }} - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: latest - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: '**/pnpm-lock.yaml' - name: Install dependencies run: pnpm install --frozen-lockfile - name: Build web package working-directory: packages/web run: pnpm run build - name: Create release archive working-directory: packages/web run: pnpm run package - name: Upload archive (artifact) uses: actions/upload-artifact@v4 with: name: web-build path: packages/web/dist/build.tar if-no-files-found: error - name: Attach archive to GitHub Release if: ${{ github.event_name == 'release' || inputs.attach_to_release == true }} uses: softprops/action-gh-release@v2 with: files: packages/web/dist/build.tar tag_name: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag_name }} fail_on_unmatched_files: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Docker metadata (tags & labels) id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY_IMAGE }} tags: | # For release events, use the release tag (e.g. v1.2.3) type=raw,value=${{ github.event.release.tag_name }},enable=${{ github.event_name == 'release' }} # For manual runs with a provided tag_name type=raw,value=${{ inputs.tag_name }},enable=${{ github.event_name == 'workflow_dispatch' && inputs.tag_name != '' }} # For manual runs without tag_name, fall back to adhoc- type=sha,format=short,prefix=adhoc-,enable=${{ github.event_name == 'workflow_dispatch' && inputs.tag_name == '' }} # Add "latest" only for full releases (not prereleases) type=raw,value=latest,enable=${{ github.event_name == 'release' && github.event.release.prerelease == false }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Buildx uses: docker/setup-buildx-action@v3 - name: Build and (maybe) push image uses: docker/build-push-action@v6 with: context: . file: ./packages/web/infra/Containerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name == 'release' && github.event.release.prerelease == false }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - name: Output image refs if: ${{ github.event_name == 'release' && github.event.release.prerelease == false }} run: "echo \"🖼️ Pushed: ${{ steps.meta.outputs.tags }}\"" - name: Explain no image push if: ${{ !(github.event_name == 'release' && github.event.release.prerelease == false) }} run: echo "ℹ️ No image pushed (prerelease or manual run)."