Release #10
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: Release | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Release tag (e.g., v0.1.0)' | |
| required: true | |
| type: string | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: pulseengine/bazel-file-ops-component | |
| jobs: | |
| build-and-release: | |
| name: Build & Release WASM Component | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| packages: write | |
| id-token: write # For Cosign keyless signing | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Setup C++ Build Tools | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential gcc g++ | |
| - name: Setup Bazel | |
| uses: bazel-contrib/[email protected] | |
| with: | |
| bazelisk-cache: true | |
| disk-cache: ${{ github.workflow }} | |
| repository-cache: true | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.23' | |
| - name: Setup TinyGo | |
| uses: acifani/setup-tinygo@v2 | |
| with: | |
| tinygo-version: '0.38.0' | |
| - name: Install Cosign | |
| uses: sigstore/cosign-installer@v3 | |
| - name: Build TinyGo WASM Component | |
| run: | | |
| echo "Building TinyGo WebAssembly component..." | |
| bazel build //tinygo:file_ops_component | |
| # Copy to a predictable location | |
| cp bazel-bin/tinygo/file_ops_component.wasm ./file_ops_component.wasm | |
| # Verify it's a valid WebAssembly module | |
| file ./file_ops_component.wasm | |
| ls -lh ./file_ops_component.wasm | |
| - name: Build AOT-Embedded WASM Component | |
| run: | | |
| echo "Building AOT-embedded WebAssembly component with multi-architecture support..." | |
| # Build multi-architecture AOT compiled artifacts | |
| echo "Compiling WASM to native code for multiple architectures..." | |
| bazel build //tinygo:file_ops_aot_multi | |
| # Build the component with embedded AOT artifacts | |
| echo "Embedding AOT artifacts as custom sections..." | |
| # Enable C++ toolchain resolution (requires cc_configure in MODULE.bazel) | |
| bazel build //tinygo:file_ops_component_aot | |
| # Copy to a predictable location | |
| cp bazel-bin/tinygo/file_ops_component_aot.wasm ./file_ops_component_aot.wasm | |
| # Verify it's a valid WebAssembly module | |
| file ./file_ops_component_aot.wasm | |
| ls -lh ./file_ops_component_aot.wasm | |
| # Show size comparison | |
| echo "Size comparison:" | |
| echo " Regular WASM: $(ls -lh file_ops_component.wasm | awk '{print $5}')" | |
| echo " AOT-embedded: $(ls -lh file_ops_component_aot.wasm | awk '{print $5}')" | |
| - name: Create SHA256 checksums | |
| run: | | |
| sha256sum file_ops_component.wasm > file_ops_component.wasm.sha256 | |
| sha256sum file_ops_component_aot.wasm > file_ops_component_aot.wasm.sha256 | |
| cat file_ops_component.wasm.sha256 | |
| cat file_ops_component_aot.wasm.sha256 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create OCI Image with WASM Component | |
| run: | | |
| # Create an OCI artifact containing the WASM file | |
| # Using oras which is designed for OCI artifacts | |
| # Install oras | |
| VERSION="1.2.2" | |
| curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz" | |
| mkdir -p oras-install/ | |
| tar -zxf "oras_${VERSION}_linux_amd64.tar.gz" -C oras-install/ | |
| sudo mv oras-install/oras /usr/local/bin/ | |
| rm -rf "oras_${VERSION}_linux_amd64.tar.gz" oras-install/ | |
| # Determine tag | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| TAG="${{ inputs.tag }}" | |
| else | |
| TAG="${{ github.event.release.tag_name }}" | |
| fi | |
| # Create OCI artifact references | |
| IMAGE_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}" | |
| IMAGE_LATEST="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" | |
| IMAGE_AOT_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}-aot" | |
| IMAGE_AOT_LATEST="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aot" | |
| # Push regular WASM file as OCI artifact | |
| echo "Publishing regular WASM component..." | |
| oras push "${IMAGE_TAG}" \ | |
| --artifact-type application/vnd.wasm.component.layer.v1+wasm \ | |
| file_ops_component.wasm:application/vnd.wasm.component.layer.v1+wasm | |
| # Tag as latest | |
| oras tag "${IMAGE_TAG}" latest | |
| # Push AOT-embedded WASM file as OCI artifact | |
| echo "Publishing AOT-embedded WASM component..." | |
| oras push "${IMAGE_AOT_TAG}" \ | |
| --artifact-type application/vnd.wasm.component.layer.v1+wasm \ | |
| file_ops_component_aot.wasm:application/vnd.wasm.component.layer.v1+wasm | |
| # Tag AOT as latest-aot | |
| oras tag "${IMAGE_AOT_TAG}" latest-aot | |
| echo "Published OCI artifacts:" | |
| echo " Regular: ${IMAGE_TAG}" | |
| echo " Regular (latest): ${IMAGE_LATEST}" | |
| echo " AOT-embedded: ${IMAGE_AOT_TAG}" | |
| echo " AOT-embedded (latest): ${IMAGE_AOT_LATEST}" | |
| echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV | |
| echo "IMAGE_LATEST=${IMAGE_LATEST}" >> $GITHUB_ENV | |
| echo "IMAGE_AOT_TAG=${IMAGE_AOT_TAG}" >> $GITHUB_ENV | |
| echo "IMAGE_AOT_LATEST=${IMAGE_AOT_LATEST}" >> $GITHUB_ENV | |
| - name: Sign OCI Image with Cosign | |
| run: | | |
| # Sign using keyless signing with GitHub OIDC | |
| echo "Signing regular WASM component..." | |
| cosign sign --yes "${IMAGE_TAG}" | |
| cosign sign --yes "${IMAGE_LATEST}" | |
| echo "Signing AOT-embedded WASM component..." | |
| cosign sign --yes "${IMAGE_AOT_TAG}" | |
| cosign sign --yes "${IMAGE_AOT_LATEST}" | |
| echo "✅ All OCI images signed with Cosign (keyless)" | |
| - name: Generate SLSA Provenance | |
| run: | | |
| # Create provenance attestation | |
| cat > provenance.json <<EOF | |
| { | |
| "buildType": "https://github.com/pulseengine/bazel-file-ops-component/release@v1", | |
| "builder": { | |
| "id": "https://github.com/actions/runner" | |
| }, | |
| "invocation": { | |
| "configSource": { | |
| "uri": "${{ github.server_url }}/${{ github.repository }}", | |
| "digest": { | |
| "sha1": "${{ github.sha }}" | |
| } | |
| } | |
| }, | |
| "metadata": { | |
| "buildStartedOn": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", | |
| "completeness": { | |
| "parameters": true, | |
| "environment": false, | |
| "materials": false | |
| } | |
| }, | |
| "materials": [ | |
| { | |
| "uri": "${{ github.server_url }}/${{ github.repository }}", | |
| "digest": { | |
| "sha1": "${{ github.sha }}" | |
| } | |
| } | |
| ] | |
| } | |
| EOF | |
| # Attest the provenance for both regular and AOT variants | |
| cosign attest --yes \ | |
| --predicate provenance.json \ | |
| --type slsaprovenance \ | |
| "${IMAGE_TAG}" | |
| cosign attest --yes \ | |
| --predicate provenance.json \ | |
| --type slsaprovenance \ | |
| "${IMAGE_AOT_TAG}" | |
| echo "✅ SLSA provenance attestation created for all variants" | |
| - name: Verify Signatures | |
| run: | | |
| # Verify the signature | |
| cosign verify \ | |
| --certificate-identity-regexp="https://github.com/${{ github.repository }}" \ | |
| --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ | |
| "${IMAGE_TAG}" || echo "Note: Signature verification may require specific conditions" | |
| echo "✅ Signature verification completed" | |
| - name: Upload Release Assets | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| file_ops_component.wasm | |
| file_ops_component.wasm.sha256 | |
| file_ops_component_aot.wasm | |
| file_ops_component_aot.wasm.sha256 | |
| body: | | |
| ## 🎉 Bazel File Operations Component Release | |
| ### 📦 What's Included | |
| **Regular WASM Component:** | |
| - `file_ops_component.wasm` - Standard WebAssembly component | |
| - `file_ops_component.wasm.sha256` - SHA256 checksum | |
| - Signed OCI artifact: `${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}` | |
| **AOT-Embedded WASM Component (NEW):** | |
| - `file_ops_component_aot.wasm` - Component with embedded AOT compiled artifacts | |
| - `file_ops_component_aot.wasm.sha256` - SHA256 checksum | |
| - Signed OCI artifact: `${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}-aot` | |
| - **Includes native code for:** Linux x64/ARM64, macOS x64/ARM64, Windows x64, Pulley64 (portable) | |
| - **Benefits:** Faster startup times, better runtime performance | |
| - **Trade-off:** Larger file size (~6x) but instant execution | |
| ### 🔐 Security Features | |
| - ✅ **OCI Artifact Signing** - All variants signed with Cosign using GitHub OIDC (keyless) | |
| - ✅ **SLSA Provenance** - Build attestation included for all variants | |
| - ✅ **SHA256 Checksums** - For download verification | |
| ### 🚀 Usage | |
| #### Download WASM Component (Regular) | |
| ```bash | |
| # Download and verify checksum | |
| wget https://github.com/${{ github.repository }}/releases/download/${TAG}/file_ops_component.wasm | |
| wget https://github.com/${{ github.repository }}/releases/download/${TAG}/file_ops_component.wasm.sha256 | |
| sha256sum -c file_ops_component.wasm.sha256 | |
| ``` | |
| #### Download WASM Component (AOT-Embedded) | |
| ```bash | |
| # Download AOT-embedded variant with native code for multiple platforms | |
| wget https://github.com/${{ github.repository }}/releases/download/${TAG}/file_ops_component_aot.wasm | |
| wget https://github.com/${{ github.repository }}/releases/download/${TAG}/file_ops_component_aot.wasm.sha256 | |
| sha256sum -c file_ops_component_aot.wasm.sha256 | |
| ``` | |
| #### Pull Signed OCI Artifact (Regular) | |
| ```bash | |
| # Pull the signed OCI artifact with oras | |
| oras pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG} | |
| # Verify signature with Cosign | |
| cosign verify \ | |
| --certificate-identity-regexp="https://github.com/${{ github.repository }}" \ | |
| --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG} | |
| # Verify SLSA provenance | |
| cosign verify-attestation \ | |
| --type slsaprovenance \ | |
| --certificate-identity-regexp="https://github.com/${{ github.repository }}" \ | |
| --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG} | |
| ``` | |
| #### Pull Signed OCI Artifact (AOT-Embedded) | |
| ```bash | |
| # Pull the AOT-embedded variant | |
| oras pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}-aot | |
| # Verify signature | |
| cosign verify \ | |
| --certificate-identity-regexp="https://github.com/${{ github.repository }}" \ | |
| --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}-aot | |
| # Verify SLSA provenance | |
| cosign verify-attestation \ | |
| --type slsaprovenance \ | |
| --certificate-identity-regexp="https://github.com/${{ github.repository }}" \ | |
| --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}-aot | |
| ``` | |
| ### 📋 Integration with rules_wasm_component | |
| See [INTEGRATION.md](https://github.com/${{ github.repository }}/blob/main/INTEGRATION.md) for details on using this component. | |
| ### 🔍 Verification | |
| All releases are: | |
| - Built in GitHub Actions with full transparency | |
| - Signed with Cosign using keyless signing (GitHub OIDC) | |
| - Attested with SLSA provenance | |
| - Checksummed with SHA256 | |
| tag_name: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.event.release.tag_name }} | |
| - name: Create Release Summary | |
| run: | | |
| # Determine tag | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| TAG="${{ inputs.tag }}" | |
| else | |
| TAG="${{ github.event.release.tag_name }}" | |
| fi | |
| echo "## 🚀 Release Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 📦 Published Artifacts" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Regular WASM Component:**" >> $GITHUB_STEP_SUMMARY | |
| echo "- **File**: \`file_ops_component.wasm\` ($(ls -lh file_ops_component.wasm | awk '{print $5}'))" >> $GITHUB_STEP_SUMMARY | |
| echo "- **OCI Artifact**: \`${IMAGE_TAG}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **OCI Artifact (latest)**: \`${IMAGE_LATEST}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**AOT-Embedded WASM Component:**" >> $GITHUB_STEP_SUMMARY | |
| echo "- **File**: \`file_ops_component_aot.wasm\` ($(ls -lh file_ops_component_aot.wasm | awk '{print $5}'))" >> $GITHUB_STEP_SUMMARY | |
| echo "- **OCI Artifact**: \`${IMAGE_AOT_TAG}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **OCI Artifact (latest)**: \`${IMAGE_AOT_LATEST}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Platforms**: Linux x64/ARM64, macOS x64/ARM64, Windows x64, Pulley64" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 🔐 Security" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ All OCI artifacts signed with Cosign (keyless OIDC)" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ SLSA provenance attestation for all variants" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ SHA256 checksums provided for all files" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY | |
| echo "- [Download WASM (Regular)](https://github.com/${{ github.repository }}/releases/tag/${TAG})" >> $GITHUB_STEP_SUMMARY | |
| echo "- [Download WASM (AOT)](https://github.com/${{ github.repository }}/releases/tag/${TAG})" >> $GITHUB_STEP_SUMMARY | |
| echo "- [Pull OCI (Regular)](${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG})" >> $GITHUB_STEP_SUMMARY | |
| echo "- [Pull OCI (AOT)](${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG}-aot)" >> $GITHUB_STEP_SUMMARY |