name: Release # This workflow handles the complete release process: # 1. Build binaries for multiple platforms (snrd, hway) # 2. Build WASM modules (vault, motor) # 3. Publish to GitHub releases, S3, and package registries # 4. Build and push Docker images for all services # 5. Publish NPM packages # 6. Push protobuf definitions to Buf Schema Registry on: push: tags: - "v[0-9]+.[0-9]+.[0-9]+" # ignore rc workflow_dispatch: permissions: contents: write packages: write id-token: write jobs: # Prepare job runs on multiple OS for native builds prepare: strategy: matrix: include: - os: ubuntu-latest goos: linux goarch: amd64 - os: ubuntu-latest goos: linux goarch: arm64 - os: macos-latest goos: darwin goarch: amd64 - os: macos-latest goos: darwin goarch: arm64 runs-on: ${{ matrix.os }} env: flags: "" steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Go uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true cache-dependency-path: "**/*.sum" - name: Install dependencies run: | go mod download # Build WASM modules make build-motr make build-vault # Set flags for workflow dispatch (nightly builds) - if: ${{ github.event_name == 'workflow_dispatch' }} shell: bash run: | echo "flags=--nightly" >> $GITHUB_ENV # Generate cache key - shell: bash run: | echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV # Cache the built artifacts - uses: actions/cache@v4 with: path: dist/${{ matrix.goos }} key: ${{ matrix.goos }}-${{ matrix.goarch }}-${{ env.sha_short }}${{ env.flags }} enableCrossOsArchive: true # Run goreleaser in split mode for snrd - name: Run GoReleaser for snrd (Split) uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser-pro version: latest args: release --clean --split --config cmd/snrd/.goreleaser.yml ${{ env.flags }} workdir: cmd/snrd env: GITHUB_TOKEN: ${{ secrets.GH_PAT_TOKEN }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} GGOOS: ${{ matrix.goos }} GGOARCH: ${{ matrix.goarch }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # Run goreleaser in split mode for hway - name: Run GoReleaser for hway (Split) uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser-pro version: latest args: release --clean --split --config cmd/hway/.goreleaser.yml ${{ env.flags }} workdir: cmd/hway env: GITHUB_TOKEN: ${{ secrets.GH_PAT_TOKEN }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} GGOOS: ${{ matrix.goos }} GGOARCH: ${{ matrix.goarch }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # WASM modules build job wasm: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Go uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true - name: Setup TinyGo uses: acifani/setup-tinygo@v2 with: tinygo-version: '0.32.0' - name: Build WASM modules run: | # Build vault WASM cd cmd/vault make build cd ../.. # Build motor WASM cd cmd/motr make build cd ../.. - name: Run GoReleaser for WASM modules uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser-pro version: latest args: release --clean --config cmd/vault/.goreleaser.yml workdir: cmd/vault env: GITHUB_TOKEN: ${{ secrets.GH_PAT_TOKEN }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name: Run GoReleaser for Motor WASM uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser-pro version: latest args: release --clean --config cmd/motr/.goreleaser.yml workdir: cmd/motr env: GITHUB_TOKEN: ${{ secrets.GH_PAT_TOKEN }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # Merge and release job combines all artifacts release: runs-on: ubuntu-latest needs: [prepare, wasm] env: flags: "" steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Go uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true cache-dependency-path: "**/*.sum" # Set flags for workflow dispatch - if: ${{ github.event_name == 'workflow_dispatch' }} shell: bash run: | echo "flags=--nightly" >> $GITHUB_ENV # Generate cache key - shell: bash run: | echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV # Restore all cached artifacts from prepare jobs - name: Restore Linux AMD64 artifacts uses: actions/cache@v4 with: path: dist/linux key: linux-amd64-${{ env.sha_short }}${{ env.flags }} enableCrossOsArchive: true - name: Restore Linux ARM64 artifacts uses: actions/cache@v4 with: path: dist/linux key: linux-arm64-${{ env.sha_short }}${{ env.flags }} enableCrossOsArchive: true - name: Restore Darwin AMD64 artifacts uses: actions/cache@v4 with: path: dist/darwin key: darwin-amd64-${{ env.sha_short }}${{ env.flags }} enableCrossOsArchive: true - name: Restore Darwin ARM64 artifacts uses: actions/cache@v4 with: path: dist/darwin key: darwin-arm64-${{ env.sha_short }}${{ env.flags }} enableCrossOsArchive: true # Merge and publish the release for snrd - name: Run GoReleaser for snrd (Merge) uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser-pro version: latest args: continue --merge --config cmd/snrd/.goreleaser.yml ${{ env.flags }} workdir: cmd/snrd env: GITHUB_TOKEN: ${{ secrets.GH_PAT_TOKEN }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # Merge and publish the release for hway - name: Run GoReleaser for hway (Merge) uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser-pro version: latest args: continue --merge --config cmd/hway/.goreleaser.yml ${{ env.flags }} workdir: cmd/hway env: GITHUB_TOKEN: ${{ secrets.GH_PAT_TOKEN }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # Protobuf publishing job protobuf: runs-on: ubuntu-latest needs: release steps: - name: Check out the repo uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Buf uses: bufbuild/buf-setup-action@v1 with: version: latest - name: Push to Buf Schema Registry uses: bufbuild/buf-push-action@v1 with: input: proto buf_token: ${{ secrets.BUF_TOKEN }} github_token: ${{ secrets.GH_PAT_TOKEN }} # NPM packages publishing job npm: runs-on: ubuntu-latest needs: release if: github.event_name == 'push' # Only on tag push, not workflow_dispatch steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' registry-url: 'https://registry.npmjs.org' - name: Setup pnpm uses: pnpm/action-setup@v2 with: version: 9 run_install: false - name: Get pnpm store directory shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - uses: actions/cache@v4 name: Setup pnpm cache with: path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - name: Install dependencies run: pnpm install --frozen-lockfile - name: Build packages run: pnpm build - name: Publish packages run: | # Update package versions to match git tag export VERSION=${GITHUB_REF#refs/tags/v} bash scripts/version-bump.sh sync-packages all # Publish to npm pnpm --filter "./packages/*" publish --access public --no-git-checks pnpm --filter "./cli/*" publish --access public --no-git-checks env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # Docker multi-platform build job docker: runs-on: ubuntu-latest needs: release permissions: contents: read packages: write strategy: matrix: include: - service: snrd dockerfile: cmd/snrd/Dockerfile description: "Sonr blockchain daemon" - service: hway dockerfile: cmd/hway/Dockerfile description: "Highway service - task processor" - service: auth dockerfile: web/auth/Dockerfile description: "Authentication web application" - service: dash dockerfile: web/dash/Dockerfile description: "Dashboard web application" - service: postgres dockerfile: etc/postgres/Dockerfile description: "PostgreSQL with extensions" steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GH_PAT_TOKEN }} - name: Log in to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: | ghcr.io/sonr-io/${{ matrix.service }} onsonr/${{ matrix.service }} tags: | type=semver,pattern={{version}} type=raw,value=latest type=raw,value=${{ inputs.tag || 'latest' }},enable=${{ github.event_name == 'workflow_dispatch' }} - name: Build and push ${{ matrix.service }} uses: docker/build-push-action@v5 with: context: . file: ${{ matrix.dockerfile }} platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: | ${{ steps.meta.outputs.labels }} org.opencontainers.image.description=${{ matrix.description }} cache-from: type=gha,scope=${{ matrix.service }} cache-to: type=gha,mode=max,scope=${{ matrix.service }}