Skip to content

update from upstream #3636

update from upstream

update from upstream #3636

Workflow file for this run

# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Build
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
contents: read
checks: write
pull-requests: write
issues: write
packages: write
env:
CARGO_TERM_COLOR: always
# set this to true in GitHub variables to enable building the container
# HAS_CONTAINER: true
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
# just a name, but storing it separately as we're nice people
RUSTFLAGS: --deny=warnings
concurrency:
# each new commit to a PR runs this workflow
# so we need to avoid a long running older one from overwriting the "pr-<number>-latest"
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
cancel-in-progress: true
jobs:
build-rust:
name: Build Rust code
uses: ./.github/workflows/build-rust.yml
secrets: inherit
build-typescript:
name: Build TypeScript code
uses: ./.github/workflows/build-typescript.yml
secrets: inherit
repo-has-container:
name: Repo has container?
runs-on: ubuntu-latest
outputs:
has_container: ${{ steps.determine.outputs.has_container }}
steps:
- name: Repo has docker container?
shell: bash
id: determine
run: |
HAS_CONTAINER="${{ vars.HAS_CONTAINER }}"
echo "has_container=${HAS_CONTAINER:-false}" >> ${GITHUB_OUTPUT}
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
docker: ${{ steps.filter.outputs.docker }}
rust: ${{ steps.filter.outputs.rust }}
typescript: ${{ steps.filter.outputs.typescript }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
submodules: true
- name: Check if we actually made changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
token: ${{ secrets.GITHUB_TOKEN }}
filters: .github/file-filters.yml
calculate-version:
name: Calculate version
runs-on: ubuntu-latest
needs:
- changes
- repo-has-container
outputs:
version: ${{ steps.version.outputs.version }}
if: |
github.event_name == 'pull_request' &&
fromJSON(needs.repo-has-container.outputs.has_container) == true &&
(
fromJSON(needs.changes.outputs.docker) == true ||
fromJSON(needs.changes.outputs.rust) == true ||
fromJSON(needs.changes.outputs.typescript) == true
)
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
fetch-depth: 0
- name: Cache dependencies
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
env:
CACHE_NAME: cargo-cache-dependencies
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-cocogitto
restore-keys: |
${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-build-${{ env.CACHE_NAME }}-
- name: Set up mold
uses: rui314/setup-mold@8ec40be1d14871f7ce8fbf273c4b33f3ff75f1d1 # v1
- name: Set up toolchain
shell: bash
run: |
rm ${HOME}/.cargo/bin/cargo-fmt
rm ${HOME}/.cargo/bin/rust-analyzer
rm ${HOME}/.cargo/bin/rustfmt
rustup update
cargo --version
- name: Get binstall
shell: bash
run: |
cd /tmp
archive="cargo-binstall-x86_64-unknown-linux-musl.tgz"
wget "https://github.com/cargo-bins/cargo-binstall/releases/latest/download/${archive}"
tar -xvf "./${archive}"
rm "./${archive}"
mv ./cargo-binstall ~/.cargo/bin/
- name: Install cocogitto to get the next version number
shell: bash
run: |
cargo binstall --no-confirm cocogitto --target x86_64-unknown-linux-musl --pkg-url "{ repo }/releases/download/{ version }/{ name }-{ version }-{ target }.tar.gz" --bin-dir "{ bin }" --pkg-fmt tgz
- name: Calculate next version
shell: bash
id: version
run: |
VERSION="$(cog bump --auto --dry-run || true)"
if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "New version: ${VERSION}"
else
VERSION="v$(cog -v get-version)"
echo "No version generated, defaulting to latest tag: ${VERSION}"
fi
# remove v
VERSION="${VERSION//v/}"
# store
echo "version=${VERSION}" >> ${GITHUB_OUTPUT}
docker-build:
name: Build Docker container
runs-on: ubuntu-latest
needs:
- calculate-version
- repo-has-container
- changes
if: |
github.event_name == 'pull_request' &&
fromJSON(needs.repo-has-container.outputs.has_container) == true &&
(!(
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled')
)) &&
(
fromJSON(needs.changes.outputs.docker) == true ||
fromJSON(needs.changes.outputs.rust) == true ||
fromJSON(needs.changes.outputs.typescript) == true
)
env:
APPLICATION_NAME: PLACEHOLDER # overridden in step 'Set application name', this is merely to satisfy the linter
PATH_TO_TAR: PLACEHOLDER # same ^
UNIQUE_TAG: PLACEHOLDER # same ^
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
- name: Get binstall
shell: bash
run: |
archive="cargo-binstall-x86_64-unknown-linux-musl.tgz"
wget "https://github.com/cargo-bins/cargo-binstall/releases/latest/download/${archive}"
tar -xvf "./${archive}"
rm "./${archive}"
mv ./cargo-binstall ~/.cargo/bin/
- name: Install binstall to do set-version
shell: bash
run: |
cargo binstall cargo-edit
- name: Set the Cargo.toml version before we copy in the data into the Docker container
shell: bash
run: |
cargo set-version ${{ needs.calculate-version.outputs.version }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
# TODO validate no changes between github.event.pull_request.head.sha and the actual current sha (representing the hypothetical merge)
- name: Lowercase the image name
shell: bash
run: |
echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
- name: Set Docker tag
shell: bash
run: |
UNIQUE_TAG=pr-${{ github.event.pull_request.base.sha }}-${{ github.event.pull_request.head.sha }}
echo "UNIQUE_TAG=${UNIQUE_TAG##*/}" >> ${GITHUB_ENV}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=${{ env.UNIQUE_TAG }}
labels: |
org.opencontainers.image.version=pr-${{ github.event.number }}
org.opencontainers.image.source=${{ github.event.pull_request.html_url }}
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set application name
shell: bash
run: |
APPLICATION_NAME=${{ github.repository }}
echo "APPLICATION_NAME=${APPLICATION_NAME##*/}" >> ${GITHUB_ENV}
- name: Build Docker image
uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
with:
build-args: |
APPLICATION_NAME=${{ env.APPLICATION_NAME }}
context: .
# this container is THE PR's artifact, and we will re-tag it
# once the PR has been accepted
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-${{ env.APPLICATION_NAME }}
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-${{ env.APPLICATION_NAME }},mode=max
platforms: linux/amd64, linux/arm64
outputs: type=oci,dest=/tmp/${{ env.UNIQUE_TAG }}.tar
- name: Upload artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: containers-${{ env.APPLICATION_NAME }}
path: /tmp/${{ env.UNIQUE_TAG }}.tar
if-no-files-found: error
retention-days: 1
docker-publish:
name: Publish Docker container
runs-on: ubuntu-latest
needs:
- docker-build
# Check if the event is not triggered by a fork
if: |
github.event.pull_request.head.repo.full_name == github.repository &&
github.event_name == 'pull_request'
env:
APPLICATION_NAME: PLACEHOLDER # overridden in step 'Set application name', this is merely to satisfy the linter
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- name: Download artifact
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
path: /tmp/containers
pattern: containers-*
merge-multiple: true
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set application name
shell: bash
run: |
APPLICATION_NAME=${{ github.repository }}
echo "APPLICATION_NAME=${APPLICATION_NAME##*/}" >> ${GITHUB_ENV}
- name: Lowercase the image name
shell: bash
run: |
echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
- name: Ensure we have oras
uses: oras-project/setup-oras@9c92598691bfef1424de2f8fae81941568f5889c # v1.2.1
- name: Load images from artifacts
shell: bash
id: image
working-directory: /tmp/containers
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | oras login -u "${{ github.actor }}" --password-stdin ${{ env.REGISTRY }}
ls -l /tmp/containers
for container in /tmp/containers/*
do
echo "Found ${container}"
tag=$(basename -- $container .tar)
oras copy --from-oci-layout "${container}:${tag}" "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${tag}"
done
- name: Extract Docker metadata
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=pr,suffix=-latest
type=raw,value=pr-${{ github.event.pull_request.base.sha }}-${{ github.event.pull_request.head.sha }}
- name: Merge images
shell: bash
working-directory: /tmp/containers
run: |
# all files in dir
containers=(*)
# yeet extension
containers=${containers[@]%.tar}
new_tags="${{ join(steps.meta.outputs.tags, ' ') }}"
new_tags=$(printf -- '--tag %s ' $new_tags)
expanded_containters_tags=$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:%s ' ${containers})
docker buildx imagetools create $new_tags $expanded_containters_tags
for new_tag in $(echo "${{ join(steps.meta.outputs.tags, ' ') }}"); do
docker buildx imagetools inspect --raw $new_tag
done
all-done:
name: All done
# this is the job that should be marked as required on GitHub. It's the only one that'll reliably trigger
# when any upstream fails: success
# when all upstream skips: pass
# when all upstream success: success
# combination of upstream skip and success: success
runs-on: ubuntu-latest
needs:
- build-rust
- build-typescript
- docker-build
- docker-publish
if: |
always()
steps:
- name: Fail!
shell: bash
if: |
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled')
run: |
echo "One / more upstream failed or was cancelled. Failing job..."
exit 1
- name: Success!
shell: bash
run: |
echo "Great success!"