v0.12.5 #11
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: "CI" | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| Docker: | |
| required: false | |
| default: false | |
| type: boolean | |
| Release: | |
| required: false | |
| default: false | |
| type: boolean | |
| push: | |
| tags: ["v*.*.*"] | |
| env: | |
| SCCACHE_GHA_ENABLED: true | |
| RUSTC_WRAPPER: sccache | |
| CARGO_TERM_COLOR: always | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| multiarch: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - variant: gnu | |
| - variant: musl | |
| name: Merge image / ${{matrix.variant}} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| attestations: write | |
| packages: write | |
| needs: [linux] | |
| if: github.event_name == 'push' || inputs.Docker | |
| steps: | |
| - name: Install Cosign | |
| uses: sigstore/cosign-installer@v3 | |
| - name: Log In to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{github.repository_owner}} | |
| password: ${{github.token}} | |
| - name: Log In to DockerHub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{secrets.DOCKERHUB_USERNAME}} | |
| password: ${{secrets.DOCKERHUB_TOKEN}} | |
| - name: Download ${{matrix.variant}} meta bake definition | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: bake-meta-${{matrix.variant}} | |
| path: ${{ runner.temp }}/${{matrix.variant}} | |
| - name: Download ${{matrix.variant}} digests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: ${{ runner.temp }}/${{matrix.variant}}/digests | |
| pattern: digests-${{matrix.variant}}-* | |
| merge-multiple: true | |
| - name: Create ${{matrix.variant}} manifest list and push | |
| working-directory: ${{ runner.temp }}/${{matrix.variant}}/digests | |
| run: | | |
| docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("ghcr.io/${{github.repository}}")) | "-t " + .) | join(" ")' ${{ runner.temp }}/${{matrix.variant}}/bake-meta.json) \ | |
| $(printf 'ghcr.io/${{github.repository}}@sha256:%s ' *) | |
| docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("index.docker.io/${{github.repository}}")) | "-t " + .) | join(" ")' ${{ runner.temp }}/${{matrix.variant}}/bake-meta.json) \ | |
| $(printf 'index.docker.io/${{github.repository}}@sha256:%s ' *) | |
| - name: Inspect ${{matrix.variant}} image | |
| id: manifest-digest | |
| run: | | |
| docker buildx imagetools inspect --format '{{json .Manifest}}' ghcr.io/${{github.repository}}:$(jq -r '.target."docker-metadata-action".args.DOCKER_META_VERSION' ${{ runner.temp }}/${{matrix.variant}}/bake-meta.json) | jq -r '.digest' > GHCR_DIGEST_SHA | |
| echo "GHCR_DIGEST_SHA=$(cat GHCR_DIGEST_SHA)" | tee -a "${GITHUB_ENV}" | |
| docker buildx imagetools inspect --format '{{json .Manifest}}' index.docker.io/${{github.repository}}:$(jq -r '.target."docker-metadata-action".args.DOCKER_META_VERSION' ${{ runner.temp }}/${{matrix.variant}}/bake-meta.json) | jq -r '.digest' > DOCKERHUB_DIGEST_SHA | |
| echo "DOCKERHUB_DIGEST_SHA=$(cat DOCKERHUB_DIGEST_SHA)" | tee -a "${GITHUB_ENV}" | |
| cosign sign --yes $(jq --arg GHCR_DIGEST_SHA "$(cat GHCR_DIGEST_SHA)" -cr '.target."docker-metadata-action".tags | map(select(startswith("ghcr.io/${{github.repository}}")) | . + "@" + $GHCR_DIGEST_SHA) | join(" ")' ${{ runner.temp }}/${{matrix.variant}}/bake-meta.json) | |
| cosign sign --yes $(jq --arg DOCKERHUB_DIGEST_SHA "$(cat DOCKERHUB_DIGEST_SHA)" -cr '.target."docker-metadata-action".tags | map(select(startswith("index.docker.io/${{github.repository}}")) | . + "@" + $DOCKERHUB_DIGEST_SHA) | join(" ")' ${{ runner.temp }}/${{matrix.variant}}/bake-meta.json) | |
| - name: Attest GHCR | |
| uses: actions/attest-build-provenance@v2 | |
| with: | |
| subject-name: ghcr.io/${{github.repository}} | |
| subject-digest: ${{ env.GHCR_DIGEST_SHA }} | |
| push-to-registry: true | |
| - name: Attest Dockerhub | |
| uses: actions/attest-build-provenance@v2 | |
| with: | |
| subject-name: index.docker.io/${{github.repository}} | |
| subject-digest: ${{ env.DOCKERHUB_DIGEST_SHA }} | |
| push-to-registry: true | |
| linux: | |
| permissions: | |
| id-token: write | |
| contents: write | |
| attestations: write | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| platform: linux/amd64 | |
| suffix: '' | |
| build_env: '' | |
| - target: x86_64-unknown-linux-musl | |
| platform: linux/amd64 | |
| suffix: '-alpine' | |
| build_env: '' | |
| - target: aarch64-unknown-linux-gnu | |
| platform: linux/arm64 | |
| suffix: '' | |
| build_env: 'JEMALLOC_SYS_WITH_LG_PAGE=16 ' | |
| - target: aarch64-unknown-linux-musl | |
| platform: linux/arm64 | |
| suffix: '-alpine' | |
| build_env: 'JEMALLOC_SYS_WITH_LG_PAGE=16 ' | |
| - target: armv7-unknown-linux-gnueabihf | |
| platform: linux/arm/v7 | |
| suffix: '' | |
| build_env: 'JEMALLOC_SYS_WITH_LG_PAGE=16 ' | |
| - target: armv7-unknown-linux-musleabihf | |
| platform: linux/arm/v7 | |
| suffix: '-alpine' | |
| build_env: 'JEMALLOC_SYS_WITH_LG_PAGE=16 ' | |
| - target: arm-unknown-linux-gnueabihf | |
| platform: linux/arm/v6 | |
| suffix: '' | |
| build_env: '' | |
| - target: arm-unknown-linux-musleabihf | |
| platform: linux/arm/v6 | |
| suffix: '-alpine' | |
| build_env: '' | |
| name: Build / ${{matrix.target}} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| with: | |
| platforms: "arm64,arm" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| with: | |
| buildkitd-config-inline: | | |
| [registry."docker.io"] | |
| mirrors = ["https://mirror.gcr.io"] | |
| driver-opts: | | |
| network=host | |
| - name: Log In to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{github.repository_owner}} | |
| password: ${{github.token}} | |
| - name: Log In to DockerHub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{secrets.DOCKERHUB_USERNAME}} | |
| password: ${{secrets.DOCKERHUB_TOKEN}} | |
| - name: Calculate shasum of external deps | |
| id: cal-dep-shasum | |
| run: | | |
| echo "checksum=$(yq -p toml -oy '.package[] | select((.source | contains("")) or (.checksum | contains("")))' Cargo.lock | sha256sum | awk '{print $1}')" >> "$GITHUB_OUTPUT" | |
| - name: Cache apt | |
| uses: actions/cache@v4 | |
| id: apt-cache | |
| with: | |
| path: | | |
| var-cache-apt | |
| var-lib-apt | |
| key: apt-cache-${{ hashFiles('Dockerfile.build') }} | |
| - name: Cache Cargo | |
| uses: actions/cache@v4 | |
| id: cargo-cache | |
| with: | |
| path: | | |
| usr-local-cargo-registry | |
| usr-local-cargo-git | |
| key: cargo-cache-${{ steps.cal-dep-shasum.outputs.checksum }} | |
| - name: Inject cache into docker | |
| uses: reproducible-containers/[email protected] | |
| with: | |
| cache-map: | | |
| { | |
| "var-cache-apt": "/var/cache/apt", | |
| "var-lib-apt": "/var/lib/apt", | |
| "usr-local-cargo-registry": "/usr/local/cargo/registry", | |
| "usr-local-cargo-git": "/usr/local/cargo/git" | |
| } | |
| skip-extraction: ${{ steps.cargo-cache.outputs.cache-hit }} && ${{ steps.apt-cache.outputs.cache-hit }} | |
| - name: Extract Metadata for Docker | |
| uses: docker/metadata-action@v5 | |
| id: meta | |
| with: | |
| images: | | |
| index.docker.io/${{github.repository}} | |
| ghcr.io/${{github.repository}} | |
| flavor: | | |
| suffix=${{matrix.suffix}},onlatest=true | |
| tags: | | |
| type=ref,event=tag | |
| type=ref,event=branch,prefix=branch- | |
| type=edge,branch=main | |
| type=semver,pattern=v{{major}}.{{minor}} | |
| - name: Build Artifact | |
| id: bake | |
| uses: docker/bake-action@v6 | |
| env: | |
| DOCKER_BUILD_RECORD_UPLOAD: false | |
| TARGET: ${{matrix.target}} | |
| GHCR_REPO: ghcr.io/${{github.repository}} | |
| BUILD_ENV: ${{matrix.build_env}} | |
| DOCKER_PLATFORM: ${{matrix.platform}} | |
| SUFFIX: ${{matrix.suffix}} | |
| with: | |
| source: . | |
| set: | | |
| *.tags= | |
| image.output=type=image,"name=ghcr.io/${{github.repository}},index.docker.io/${{github.repository}}",push-by-digest=true,name-canonical=true,push=true,compression=zstd,compression-level=9,force-compression=true,oci-mediatypes=true | |
| files: | | |
| docker-bake.hcl | |
| ${{ steps.meta.outputs.bake-file }} | |
| targets: ${{(github.event_name == 'push' || inputs.Docker) && 'build,image' || 'build'}} | |
| - name: Upload Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: artifact-${{matrix.target}} | |
| path: | | |
| artifact | |
| !artifact/*.json | |
| - name: Export digest & Rename meta bake definition file | |
| if: github.event_name == 'push' || inputs.Docker | |
| run: | | |
| mv "${{ steps.meta.outputs.bake-file }}" "${{ runner.temp }}/bake-meta.json" | |
| mkdir -p ${{ runner.temp }}/digests | |
| digest="${{ fromJSON(steps.bake.outputs.metadata).image['containerimage.digest'] }}" | |
| touch "${{ runner.temp }}/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| if: github.event_name == 'push' || inputs.Docker | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: digests-${{matrix.suffix == '' && 'gnu' || 'musl'}}-${{ matrix.target }} | |
| path: ${{ runner.temp }}/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| - name: Upload GNU meta bake definition | |
| uses: actions/upload-artifact@v4 | |
| if: (github.event_name == 'push' || inputs.Docker) && endsWith(matrix.target,'gnu') && startsWith(matrix.target,'x86') | |
| with: | |
| name: bake-meta-gnu | |
| path: ${{ runner.temp }}/bake-meta.json | |
| if-no-files-found: error | |
| retention-days: 1 | |
| - name: Upload musl meta bake definition | |
| uses: actions/upload-artifact@v4 | |
| if: (github.event_name == 'push' || inputs.Docker) && endsWith(matrix.target,'musl') && startsWith(matrix.target,'x86') | |
| with: | |
| name: bake-meta-musl | |
| path: ${{ runner.temp }}/bake-meta.json | |
| if-no-files-found: error | |
| retention-days: 1 | |
| windows: | |
| name: Build / ${{matrix.target}} | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # - target: aarch64-pc-windows-msvc | |
| - target: x86_64-pc-windows-msvc | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Run sccache-cache | |
| uses: mozilla-actions/[email protected] | |
| with: | |
| disable_annotations: true | |
| - name: Build | |
| run: | | |
| rustup target add ${{matrix.target}} | |
| cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "sqlite postgres mysql rocks elastic s3 redis azure nats enterprise" | |
| cargo build --release --target ${{matrix.target}} -p stalwart-cli | |
| mkdir -p artifacts | |
| mv ./target/${{matrix.target}}/release/stalwart.exe ./artifacts/stalwart.exe | |
| mv ./target/${{matrix.target}}/release/stalwart-cli.exe ./artifacts/stalwart-cli.exe | |
| - name: Upload Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: artifact-${{matrix.target}} | |
| path: artifacts | |
| macos: | |
| name: Build / ${{matrix.target}} | |
| runs-on: macos-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: aarch64-apple-darwin | |
| - target: x86_64-apple-darwin | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Run sccache-cache | |
| uses: mozilla-actions/[email protected] | |
| with: | |
| disable_annotations: true | |
| - name: Build FoundationDB Edition | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| rustup target add ${{matrix.target}} | |
| # Get latest FoundationDB installer | |
| curl --retry 5 -Lso foundationdb.pkg "$(gh api -X GET /repos/apple/foundationdb/releases --jq '.[] | select(.prerelease == false) | .assets[] | select(.name | test("${{startsWith(matrix.target, 'x86') && 'x86_64' || 'arm64'}}" + ".pkg$")) | .browser_download_url' | head -n1)" | |
| sudo installer -allowUntrusted -dumplog -pkg foundationdb.pkg -target / | |
| cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "foundationdb elastic s3 redis nats enterprise" | |
| mkdir -p artifacts | |
| mv ./target/${{matrix.target}}/release/stalwart ./artifacts/stalwart-foundationdb | |
| - name: Build | |
| run: | | |
| rustup target add ${{matrix.target}} | |
| cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "sqlite postgres mysql rocks elastic s3 redis azure nats enterprise" | |
| cargo build --release --target ${{matrix.target}} -p stalwart-cli | |
| mkdir -p artifacts | |
| mv ./target/${{matrix.target}}/release/stalwart ./artifacts/stalwart | |
| mv ./target/${{matrix.target}}/release/stalwart-cli ./artifacts/stalwart-cli | |
| - name: Upload Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: artifact-${{matrix.target}} | |
| path: artifacts | |
| release: | |
| name: Release | |
| permissions: | |
| id-token: write | |
| contents: write | |
| attestations: write | |
| if: github.event_name == 'push' || inputs.Release | |
| needs: [linux, windows, macos] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download Artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: archive | |
| pattern: artifact-* | |
| - name: Compress | |
| run: | | |
| set -eux | |
| BASE_DIR="$(pwd)/archive" | |
| compress_files() { | |
| local dir="$1" | |
| local archive_dir_name="${dir#artifact-}" | |
| cd "$dir" | |
| # Process each file in the directory | |
| for file in `ls`; do | |
| filename="${file%.*}" | |
| extension="${file##*.}" | |
| if [ "$extension" = "exe" ]; then | |
| 7z a -tzip "${filename}-${archive_dir_name}.zip" "$file" > /dev/null | |
| else | |
| tar -czf "${filename}-${archive_dir_name}.tar.gz" "$file" | |
| fi | |
| done | |
| cd $BASE_DIR | |
| } | |
| cd $BASE_DIR | |
| for arch_dir in `ls`; do | |
| dir_name=$(basename "$arch_dir") | |
| compress_files "$dir_name" | |
| done | |
| - name: Attest binary | |
| id: attest | |
| uses: actions/attest-build-provenance@v2 | |
| with: | |
| subject-path: | | |
| archive/**/*.tar.gz | |
| archive/**/*.zip | |
| - name: Use cosign to sign existing artifacts | |
| uses: sigstore/[email protected] | |
| with: | |
| inputs: | | |
| archive/**/*.tar.gz | |
| archive/**/*.zip | |
| - name: Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| archive/**/*.tar.gz | |
| archive/**/*.zip | |
| archive/**/*.sigstore.json | |
| prerelease: ${{!startsWith(github.ref, 'refs/tags/') || null}} | |
| tag_name: ${{!startsWith(github.ref, 'refs/tags/') && 'nightly' || null}} | |
| # TODO add instructions about using cosign to verify binary artifact | |
| append_body: true | |
| body: | | |
| <hr /> | |
| ### Check binary attestation at [here](${{ steps.attest.outputs.attestation-url }}) |