name: CI on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: permissions: contents: read jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: { python-version: "3.11" } - run: pip install -r requirements.txt - run: pip install -r requirements-audit.txt - run: python3 -m pip_audit -r requirements.txt --strict - run: python3 -m pytest tests/ -q build-release: runs-on: ubuntu-latest needs: lint steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Build deterministic release bundle run: | SOURCE_DATE_EPOCH="$(git show -s --format=%ct "$GITHUB_SHA")" python3 scripts/build_release.py \ --root . \ --output-dir dist \ --commit "$GITHUB_SHA" \ --source-date-epoch "$SOURCE_DATE_EPOCH" - name: Upload tested release bundle uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: name: release-bundle path: dist/ browser-journey: runs-on: ubuntu-latest needs: build-release env: STACKCHAIN_RUN_RELEASE_E2E: "1" steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: { python-version: "3.11" } - name: Download assembled release bundle uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: release-bundle path: dist - name: Install browser test dependencies run: | pip install -r requirements-e2e.txt python3 -m playwright install --with-deps chromium - name: Exercise packaged mobile work journeys run: python3 -m pytest tests/e2e -q release-candidate: runs-on: ubuntu-latest needs: [lint, build-release, browser-journey] if: github.event_name == 'push' && github.ref == 'refs/heads/main' permissions: contents: write steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download tested release bundle uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: release-bundle path: dist - name: Verify and publish release candidate env: TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail TARGET="${{ github.sha }}" TAG="v0.1.0-rc.${{ github.run_number }}" RELEASE_URL="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" (cd dist && sha256sum -c ./*.sha256) python3 scripts/verify_release.py --input-dir dist --commit "$TARGET" --repository . printf '{"tag_name":"%s","target_commitish":"%s","name":"Release Candidate %s","body":"CI-tested release candidate for commit %s. Verify downloads with the attached SHA-256 checksum.","draft":true,"prerelease":true}\n' \ "$TAG" "$TARGET" "$TAG" "$TARGET" > /tmp/release.json curl --fail-with-body -sS -X POST "$RELEASE_URL" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/json" \ --data-binary @/tmp/release.json > /tmp/release-response.json RELEASE_ID="$(python3 -c 'import json; print(json.load(open("/tmp/release-response.json"))["id"])')" for ASSET in dist/*; do NAME="$(basename "$ASSET")" ENCODED_NAME="$(python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1]))' "$NAME")" curl --fail-with-body -sS -X POST "$RELEASE_URL/$RELEASE_ID/assets?name=$ENCODED_NAME" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/octet-stream" \ --data-binary "@$ASSET" done printf '{"draft":false,"prerelease":true}\n' > /tmp/publish.json curl --fail-with-body -sS -X PATCH "$RELEASE_URL/$RELEASE_ID" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/json" \ --data-binary @/tmp/publish.json