name: Build on: push: branches: [ main ] tags: - 'v*' # Only run for pull requests if relevant files were changed pull_request: branches: [ main ] paths: - Dockerfile - docker-bake.hcl - .github/workflows/build.yaml concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: CARGO_TERM_COLOR: always CARGO_NET_GIT_FETCH_WITH_CLI: "true" SCCACHE_GHA_ENABLED: "true" RUSTC_WRAPPER: "sccache" IMAGE: ghcr.io/matrix-org/matrix-authentication-service IMAGE_SYN2MAS: ghcr.io/matrix-org/matrix-authentication-service/syn2mas BUILDCACHE: ghcr.io/matrix-org/matrix-authentication-service/buildcache jobs: build-binaries: name: Build binaries runs-on: ubuntu-22.04 env: SDKROOT: /opt/MacOSX11.3.sdk permissions: contents: read steps: - name: Checkout the code uses: actions/checkout@v4.1.1 - name: Setup OPA uses: open-policy-agent/setup-opa@v2.1.0 with: version: 0.58.0 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: | x86_64-unknown-linux-musl aarch64-unknown-linux-musl x86_64-apple-darwin aarch64-apple-darwin - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.3 - name: Install zig uses: goto-bus-stop/setup-zig@v2 with: version: 0.11.0 - name: Install cargo-zigbuild run: curl -L https://github.com/rust-cross/cargo-zigbuild/releases/download/v0.17.3/cargo-zigbuild-v0.17.3.x86_64-unknown-linux-musl.tar.gz | tar -z -x -C /usr/local/bin - name: Download the macOS SDK run: curl -L "https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz" | tar -J -x -C /opt - name: Install frontend Node uses: actions/setup-node@v4.0.0 with: node-version: 18 - name: Install frontend Node dependencies working-directory: ./frontend run: npm ci - name: Build frontend working-directory: ./frontend run: npm run build - name: Build policies working-directory: ./policies run: make - name: Force Cargo to create the target directory # Run `cargo clean` with an empty package name to force it to create the target directory # This fails because there is no package with an empty name, but the target directory is created # See https://github.com/rust-lang/cargo/issues/12441 # This is needed because `cargo-zigbuild` sometimes (wrongly) creates the target directory # See https://github.com/rust-cross/cargo-zigbuild/issues/165 run: | cargo clean -p '' \ --target x86_64-unknown-linux-musl \ --target aarch64-unknown-linux-musl \ --target x86_64-apple-darwin \ --target aarch64-apple-darwin \ || true - name: Build the binary run: | cargo zigbuild \ --release \ --target x86_64-unknown-linux-musl \ --target aarch64-unknown-linux-musl \ --target x86_64-apple-darwin \ --target aarch64-apple-darwin \ --no-default-features \ --features dist \ -p mas-cli - name: Upload the artifacts uses: actions/upload-artifact@v3.1.3 with: name: binaries path: | target/*/release/mas-cli frontend/dist/ policies/policy.wasm templates/ translations/ LICENSE build-image: name: Build and push Docker image runs-on: ubuntu-latest outputs: metadata: ${{ steps.bake.outputs.metadata }} permissions: contents: read packages: write id-token: write steps: - name: Checkout the code uses: actions/checkout@v4.1.1 - name: Docker meta id: meta uses: docker/metadata-action@v5.0.0 with: images: "${{ env.IMAGE }}" bake-target: docker-metadata-action flavor: | latest=auto tags: | type=ref,event=branch type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha - name: Docker meta (debug variant) id: meta-debug uses: docker/metadata-action@v5.0.0 with: images: "${{ env.IMAGE }}" bake-target: docker-metadata-action-debug flavor: | latest=auto suffix=-debug,onlatest=true tags: | type=ref,event=branch type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha - name: Docker meta (syn2mas) id: meta-syn2mas uses: docker/metadata-action@v5.0.0 with: images: "${{ env.IMAGE_SYN2MAS }}" bake-target: docker-metadata-action-syn2mas flavor: | latest=auto tags: | type=ref,event=branch type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha - name: Setup Cosign uses: sigstore/cosign-installer@v3.2.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.0.0 with: config-inline: | [registry."docker.io"] mirrors = ["mirror.gcr.io"] - name: Login to GitHub Container Registry if: github.event_name != 'pull_request' uses: docker/login-action@v3.0.0 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} # For pull-requests, only read from the cache, do not try to push to the # cache or the image itself - name: Build uses: docker/bake-action@v4.0.0 if: github.event_name == 'pull_request' with: files: | docker-bake.hcl ${{ steps.meta.outputs.bake-file }} ${{ steps.meta-debug.outputs.bake-file }} ${{ steps.meta-syn2mas.outputs.bake-file }} set: | base.context=https://github.com/${{ github.repository }}.git#${{ github.ref }} syn2mas.context=https://github.com/${{ github.repository }}.git#${{ github.ref }}:tools/syn2mas/ base.cache-from=type=registry,ref=${{ env.BUILDCACHE }}:buildcache - name: Build and push id: bake uses: docker/bake-action@v4.0.0 if: github.event_name != 'pull_request' with: files: | docker-bake.hcl ${{ steps.meta.outputs.bake-file }} ${{ steps.meta-debug.outputs.bake-file }} ${{ steps.meta-syn2mas.outputs.bake-file }} set: | base.context=https://github.com/${{ github.repository }}.git#${{ github.ref }} syn2mas.context=https://github.com/${{ github.repository }}.git#${{ github.ref }}:tools/syn2mas/ base.output=type=image,push=true base.cache-from=type=registry,ref=${{ env.BUILDCACHE }}:buildcache base.cache-to=type=registry,ref=${{ env.BUILDCACHE }}:buildcache,mode=max - name: Sign the images with GitHub Actions provided token # Only sign on tags and on commits on main branch if: | github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') run: |- cosign sign --yes \ "${{ env.IMAGE }}@${{ fromJSON(steps.bake.outputs.metadata).regular['containerimage.digest'] }}" \ "${{ env.IMAGE }}@${{ fromJSON(steps.bake.outputs.metadata).debug['containerimage.digest'] }}" \ "${{ env.IMAGE_SYN2MAS }}@${{ fromJSON(steps.bake.outputs.metadata).syn2mas['containerimage.digest'] }}" syn2mas: name: Release syn2mas on NPM runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - name: Checkout the code uses: actions/checkout@v4.1.1 - name: Install Node uses: actions/setup-node@v4.0.0 with: node-version-file: ./tools/syn2mas/.nvmrc - name: Install Node dependencies working-directory: ./tools/syn2mas run: npm ci - name: Publish uses: JS-DevTools/npm-publish@v3 with: package: ./tools/syn2mas token: ${{ secrets.NPM_TOKEN }} provenance: true dry-run: ${{ !startsWith(github.ref, 'refs/tags/') }} release: name: Release if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest needs: - build-binaries - build-image - syn2mas steps: - name: Download the artifacts from the previous job uses: actions/download-artifact@v3 with: name: binaries path: artifacts - name: Prepare the archive directory run: | mkdir -p dist/share/ mv artifacts/policies/policy.wasm dist/share/policy.wasm mv artifacts/frontend/dist/manifest.json dist/share/manifest.json mv artifacts/frontend/dist/ dist/share/assets mv artifacts/templates/ dist/share/templates mv artifacts/translations/ dist/share/translations mv artifacts/LICENSE dist/LICENSE chmod -R u=rwX,go=rX dist/ - name: Create the archives run: | for arch in x86_64 aarch64; do mv artifacts/target/${arch}-unknown-linux-musl/release/mas-cli dist/mas-cli chmod u=rwx,go=rx dist/mas-cli tar -czvf mas-cli-${arch}-linux.tar.gz --owner=0 --group=0 -C dist/ . mv artifacts/target/${arch}-apple-darwin/release/mas-cli dist/mas-cli chmod u=rwx,go=rx dist/mas-cli tar -czvf mas-cli-${arch}-macos.tar.gz --owner=0 --group=0 -C dist/ . done - name: Prepare a release uses: softprops/action-gh-release@v1 with: body: | ### Docker image Regular image: - Digest: ``` ${{ env.IMAGE }}@${{ fromJSON(needs.build-image.outputs.metadata).regular['containerimage.digest'] }} ``` - Tags: ``` ${{ fromJSON(needs.build-image.outputs.metadata).regular['image.name'] }} ``` Debug variant: - Digest: ``` ${{ env.IMAGE }}@${{ fromJSON(needs.build-image.outputs.metadata).debug['containerimage.digest'] }} ``` - Tags: ``` ${{ fromJSON(needs.build-image.outputs.metadata).debug['image.name'] }} ``` `syn2mas` migration tool: - Digest: ``` ${{ env.IMAGE_SYN2MAS }}@${{ fromJSON(needs.build-image.outputs.metadata).syn2mas['containerimage.digest'] }} ``` - Tags: ``` ${{ fromJSON(needs.build-image.outputs.metadata).syn2mas['image.name'] }} ``` files: | mas-cli-aarch64-linux.tar.gz mas-cli-aarch64-macos.tar.gz mas-cli-x86_64-linux.tar.gz mas-cli-x86_64-macos.tar.gz draft: true