chore: release 0.4.3 (#481) #18
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: Build | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| - "tempo-wallet@*" | |
| - "tempo-request@*" | |
| - "tempo-cards@*" | |
| env: | |
| CARGO_TERM_COLOR: always | |
| CARGO_NET_GIT_FETCH_WITH_CLI: "true" | |
| jobs: | |
| parse-tag: | |
| name: Parse tag | |
| permissions: | |
| contents: read | |
| runs-on: ubuntu-latest | |
| outputs: | |
| packages: ${{ steps.parse.outputs.packages }} | |
| version: ${{ steps.parse.outputs.version }} | |
| release_tag: ${{ steps.parse.outputs.release_tag }} | |
| steps: | |
| - name: Parse release scope and version from tag | |
| id: parse | |
| run: | | |
| TAG="${GITHUB_REF#refs/tags/}" | |
| if [[ "$TAG" == v* ]]; then | |
| VERSION="${TAG#v}" | |
| PACKAGES='["tempo-wallet","tempo-request","tempo-cards"]' | |
| RELEASE_TAG="$TAG" | |
| elif [[ "$TAG" == *"@"* ]]; then | |
| PACKAGE="${TAG%%@*}" | |
| VERSION="${TAG#*@}" | |
| RELEASE_TAG="$TAG" | |
| if [[ "$PACKAGE" == "tempo-wallet" || "$PACKAGE" == "tempo-request" || "$PACKAGE" == "tempo-cards" ]]; then | |
| PACKAGES="[\"${PACKAGE}\"]" | |
| else | |
| echo "Unsupported package in tag: ${PACKAGE}" >&2 | |
| exit 1 | |
| fi | |
| else | |
| echo "Unsupported tag format: ${TAG}" >&2 | |
| exit 1 | |
| fi | |
| { | |
| echo "packages=${PACKAGES}" | |
| echo "version=${VERSION}" | |
| echo "release_tag=${RELEASE_TAG}" | |
| } >> "$GITHUB_OUTPUT" | |
| echo "Tag: ${TAG}, packages: ${PACKAGES}, version: ${VERSION}, release tag: ${RELEASE_TAG}" | |
| build: | |
| name: Build ${{ matrix.package }} (${{ matrix.build.target }}) | |
| permissions: | |
| contents: read | |
| # Required by actions/attest for keyless Sigstore signing. | |
| id-token: write | |
| attestations: write | |
| needs: [parse-tag] | |
| runs-on: ${{ matrix.build.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| package: ${{ fromJson(needs.parse-tag.outputs.packages) }} | |
| build: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| suffix: linux-amd64 | |
| - os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| suffix: linux-arm64 | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| suffix: darwin-amd64 | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| suffix: darwin-arm64 | |
| env: | |
| PACKAGE: ${{ matrix.package }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| target: ${{ matrix.build.target }} | |
| - name: Build release binary | |
| run: cargo build --locked --release --target ${{ matrix.build.target }} -p ${{ env.PACKAGE }} | |
| - run: strip target/${{ matrix.build.target }}/release/${{ env.PACKAGE }} | |
| - run: mv target/${{ matrix.build.target }}/release/${{ env.PACKAGE }} ${{ env.PACKAGE }}-${{ matrix.build.suffix }} | |
| - name: Generate sha256 | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| BIN="${PACKAGE}-${{ matrix.build.suffix }}" | |
| if command -v sha256sum >/dev/null 2>&1; then | |
| sha256sum "$BIN" > "$BIN.sha256" | |
| else | |
| shasum -a 256 "$BIN" > "$BIN.sha256" | |
| fi | |
| cat "$BIN.sha256" | |
| - name: Generate SBOM (SPDX-JSON) | |
| uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| with: | |
| file: ${{ env.PACKAGE }}-${{ matrix.build.suffix }} | |
| format: spdx-json | |
| output-file: ${{ env.PACKAGE }}-${{ matrix.build.suffix }}.spdx.json | |
| upload-artifact: false | |
| upload-release-assets: false | |
| - name: Attest SBOM | |
| uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 | |
| with: | |
| subject-path: ${{ env.PACKAGE }}-${{ matrix.build.suffix }} | |
| sbom-path: ${{ env.PACKAGE }}-${{ matrix.build.suffix }}.spdx.json | |
| - name: Attest build provenance (SLSA v1) | |
| uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 | |
| with: | |
| subject-path: ${{ env.PACKAGE }}-${{ matrix.build.suffix }} | |
| - name: Install cosign | |
| uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 | |
| - name: Sign binary with cosign (keyless) | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| BIN="${PACKAGE}-${{ matrix.build.suffix }}" | |
| cosign sign-blob --yes \ | |
| --bundle "${BIN}.sigstore.json" \ | |
| "$BIN" | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ${{ env.PACKAGE }}-${{ matrix.build.suffix }} | |
| path: | | |
| ${{ env.PACKAGE }}-${{ matrix.build.suffix }} | |
| ${{ env.PACKAGE }}-${{ matrix.build.suffix }}.sha256 | |
| ${{ env.PACKAGE }}-${{ matrix.build.suffix }}.spdx.json | |
| ${{ env.PACKAGE }}-${{ matrix.build.suffix }}.sigstore.json | |
| if-no-files-found: error | |
| publish: | |
| name: Publish ${{ matrix.package }} | |
| environment: release | |
| permissions: | |
| contents: write | |
| needs: [parse-tag, build] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| package: ${{ fromJson(needs.parse-tag.outputs.packages) }} | |
| env: | |
| PACKAGE: ${{ matrix.package }} | |
| VERSION: ${{ needs.parse-tag.outputs.version }} | |
| RELEASE_TAG: ${{ needs.parse-tag.outputs.release_tag }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: artifacts | |
| pattern: ${{ env.PACKAGE }}-* | |
| merge-multiple: true | |
| - name: Wait for GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| TAG="${RELEASE_TAG}" | |
| for i in $(seq 1 40); do | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| echo "Release ${TAG} found" | |
| exit 0 | |
| fi | |
| echo "Waiting for release ${TAG}... (attempt ${i}/40)" | |
| sleep 15 | |
| done | |
| echo "Release ${TAG} was not created in time" >&2 | |
| exit 1 | |
| - name: Upload to GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| TAG="${RELEASE_TAG}" | |
| gh release upload "$TAG" artifacts/* --clobber | |
| - name: Build release signer | |
| run: cargo build --release -p tempo-sign | |
| - name: Sign release binaries | |
| env: | |
| RELEASE_SIGNING_KEY: ${{ secrets.RELEASE_SIGNING_KEY }} | |
| run: | | |
| echo -n "$RELEASE_SIGNING_KEY" | base64 -d > /tmp/release.key | |
| URL_PREFIX="https://cli.tempo.xyz/extensions/${PACKAGE}" | |
| declare -A PKG_DESC=( | |
| [tempo-wallet]="Manage your Tempo Wallet" | |
| [tempo-request]="Make an HTTP request" | |
| [tempo-cards]="Issue and manage Tempo wallet-backed cards" | |
| ) | |
| SIGN_ARGS=( | |
| --key-file /tmp/release.key | |
| --artifacts-dir artifacts | |
| --version "$VERSION" | |
| --base-url "$URL_PREFIX" | |
| --description "${PKG_DESC[$PACKAGE]}" | |
| --output "artifacts/${PACKAGE}-manifest.json" | |
| ) | |
| if [ "$PACKAGE" = "tempo-request" ] && [ -f "SKILL.md" ]; then | |
| SKILL_SHA256=$(sha256sum "SKILL.md" | cut -d' ' -f1) | |
| SIGN_ARGS+=( | |
| --skill "${URL_PREFIX}/v${VERSION}/SKILL.md" | |
| --skill-sha256 "$SKILL_SHA256" | |
| --skill-file "SKILL.md" | |
| ) | |
| fi | |
| ./target/release/tempo-sign sign "${SIGN_ARGS[@]}" | |
| rm /tmp/release.key | |
| - name: Upload to R2 | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| AWS_ENDPOINT_URL: https://${{ secrets.CF_ACCOUNT_ID }}.r2.cloudflarestorage.com | |
| run: | | |
| aws configure set default.s3.multipart_threshold 200MB | |
| PREFIX="extensions/${PACKAGE}" | |
| VTAG="v${VERSION}" | |
| # Binaries (latest + versioned) | |
| for f in "artifacts/${PACKAGE}"-linux-* "artifacts/${PACKAGE}"-darwin-*; do | |
| [ -f "$f" ] || continue | |
| BASENAME=$(basename "$f") | |
| aws s3 cp "$f" "s3://tempo-cli/${PREFIX}/${BASENAME}" --endpoint-url "$AWS_ENDPOINT_URL" | |
| aws s3 cp "$f" "s3://tempo-cli/${PREFIX}/${VTAG}/${BASENAME}" --endpoint-url "$AWS_ENDPOINT_URL" | |
| done | |
| # Signed manifest (latest + versioned) | |
| aws s3 cp "artifacts/${PACKAGE}-manifest.json" "s3://tempo-cli/${PREFIX}/manifest.json" --endpoint-url "$AWS_ENDPOINT_URL" | |
| aws s3 cp "artifacts/${PACKAGE}-manifest.json" "s3://tempo-cli/${PREFIX}/${VTAG}/manifest.json" --endpoint-url "$AWS_ENDPOINT_URL" | |
| # SKILL.md (versioned snapshot, only for tempo-request) | |
| if [ "$PACKAGE" = "tempo-request" ] && [ -f "SKILL.md" ]; then | |
| aws s3 cp "SKILL.md" "s3://tempo-cli/${PREFIX}/${VTAG}/SKILL.md" --endpoint-url "$AWS_ENDPOINT_URL" --content-type "text/markdown" | |
| fi | |
| # VERSION | |
| echo "${VERSION}" | aws s3 cp - "s3://tempo-cli/${PREFIX}/VERSION" --endpoint-url "$AWS_ENDPOINT_URL" --content-type "text/plain" | |
| echo "Released ${PACKAGE}@${VERSION}" |