Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch the nightly build to producing a multiarch docker image that supports both x86_64 and arm64 #133

Merged
merged 4 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 127 additions & 19 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,158 @@ on:
branches:
- 'main'

concurrency:
group: ${{ github.ref }}-nightly
cancel-in-progress: true

env:
REGISTRY_IMAGE: clux/muslrust

jobs:
docker:
build:
name: 'Nightly Build'
runs-on: 'ubuntu-latest'
strategy:
fail-fast: false
matrix:
platform: [linux/amd64, linux/arm64]
include:
- platform: linux/amd64
dockerfile: Dockerfile.x86_64
arch: amd64
target_dir: x86_64-unknown-linux-musl
- platform: linux/arm64
dockerfile: Dockerfile.arm64
arch: arm64
target_dir: aarch64-unknown-linux-musl
steps:
- uses: 'actions/checkout@v2'
- uses: extractions/setup-just@v1

- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: clux
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build nightly image
uses: docker/build-push-action@v2
id: build
uses: docker/build-push-action@v3
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
file: ${{ matrix.dockerfile }}
push: false
load: true
tags: rustmusl-temp
build-args: |
CHANNEL=nightly
tags: clux/muslrust:temp

- name: Compute tags
- name: Run tests
shell: bash
run: |
docker buildx build --platform ${{ matrix.platform }} --output type=docker -t test-runner - < Dockerfile.test-runner
TARGET_DIR=${{ matrix.target_dir }} PLATFORM=${{ matrix.platform }} just test

# The date/channel/version are expected to be the same on both architectures and are needed for the merge step.
# We store them here since it makes the merge step a bit easier - it doesn't need to figure out which of the
# architectures it can run (to extract the rust version). The problem is that it appears we can't run images
# that were built by docker buildx (the build-push-action step) locally. They get pushed to dockerhub but are
# only identifiable by their digest and it appears docker does not let us select an image that way.
# Not the most elegant, but it works.
- name: Store tag info
shell: bash
run: |
docker run clux/muslrust:temp rustc --version
RUST_VER="$(docker run clux/muslrust:temp rustc --version | grep -oE "[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]")"
mkdir -p /tmp/tags
RUST_DATE="$(date +"%Y-%m-%d")"
RUST_CHANNEL=nightly
echo "TAG1=clux/muslrust:${RUST_CHANNEL}" >> $GITHUB_ENV
echo "TAG2=clux/muslrust:${RUST_CHANNEL}-${RUST_DATE}" >> $GITHUB_ENV
echo "TAG3=clux/muslrust:${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE}" >> $GITHUB_ENV
RUST_VER="$(docker run --platform ${{ matrix.platform }} rustmusl-temp rustc --version | grep -oE "[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]")"

- name: Run tests
echo $RUST_DATE > /tmp/tags/rust-date
echo $RUST_CHANNEL > /tmp/tags/rust-channel
echo $RUST_VER > /tmp/tags/rust-ver

- name: Tag and push
shell: bash
run: just test
run: |
RUST_DATE=$(cat /tmp/tags/rust-date)
RUST_CHANNEL=$(cat /tmp/tags/rust-channel)
RUST_VER=$(cat /tmp/tags/rust-ver)

- name: Push image under computed tags
uses: docker/build-push-action@v2
TAG_NAME="${{ matrix.arch }}-${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE}"

docker tag rustmusl-temp ${{ env.REGISTRY_IMAGE }}:$TAG_NAME
docker push ${{ env.REGISTRY_IMAGE }}:$TAG_NAME

- name: Upload tags
uses: actions/upload-artifact@v4
with:
context: .
build-args: |
CHANNEL=nightly
push: ${{ github.event_name != 'pull_request' }}
tags: clux/muslrust:latest,${{ env.TAG1 }},${{ env.TAG2 }},${{ env.TAG3 }}
name: tags
path: /tmp/tags
if-no-files-found: error
retention-days: 1
overwrite: true

merge:
runs-on: ubuntu-latest
needs:
- build
steps:

-
name: Download tags
uses: actions/download-artifact@v4
with:
path: /tmp/tags
name: tags

-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: clux
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Create manifest list and push multi-platform images
run: |
RUST_DATE=$(cat /tmp/tags/rust-date)
RUST_CHANNEL=$(cat /tmp/tags/rust-channel)
RUST_VER=$(cat /tmp/tags/rust-ver)

for tag in latest ${RUST_CHANNEL} ${RUST_CHANNEL}-${RUST_DATE} ${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE}; do
docker buildx imagetools create -t ${{ env.REGISTRY_IMAGE }}:$tag \
${{ env.REGISTRY_IMAGE }}:amd64-${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE} \
${{ env.REGISTRY_IMAGE }}:arm64-${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE}
done

-
name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:latest
172 changes: 142 additions & 30 deletions .github/workflows/stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,40 @@ on:
branches:
- 'main'

concurrency:
group: ${{ github.ref }}-stable
cancel-in-progress: true

env:
REGISTRY_IMAGE: clux/muslrust

jobs:
docker:
build:
name: 'Stable Build'
runs-on: 'ubuntu-latest'
strategy:
fail-fast: false
matrix:
platform: [linux/amd64, linux/arm64]
include:
- platform: linux/amd64
dockerfile: Dockerfile.x86_64
arch: amd64
target_dir: x86_64-unknown-linux-musl
- platform: linux/arm64
dockerfile: Dockerfile.arm64
arch: arm64
target_dir: aarch64-unknown-linux-musl
steps:
- uses: 'actions/checkout@v2'
- uses: extractions/setup-just@v1

- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: clux
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Check if we need a new stable
id: stablecheck
shell: bash
Expand All @@ -27,59 +53,145 @@ jobs:
echo '::set-output name=BUILD::YES'
else
echo "Stable tag found; skipping all build steps"
# Setting dummy tag evars to prevent steps below from failing
echo "TAG1=clux/muslrust:no1" >> $GITHUB_ENV
echo "TAG2=clux/muslrust:no2" >> $GITHUB_ENV
echo "TAG3=clux/muslrust:no3" >> $GITHUB_ENV
fi

- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build stable image
id: build
uses: docker/build-push-action@v3
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
file: ${{ matrix.dockerfile }}
push: false
load: true
tags: rustmusl-temp
build-args: |
CHANNEL=stable
tags: clux/muslrust:temp
if: ${{ steps.stablecheck.outputs.BUILD }}

- name: Compute tags
- name: Run tests
if: ${{ steps.stablecheck.outputs.BUILD }}
shell: bash
run: |
docker run clux/muslrust:temp rustc --version
RUST_VER="$(docker run clux/muslrust:temp rustc --version | grep -oE "[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]")"
docker buildx build --platform ${{ matrix.platform }} --output type=docker -t test-runner - < Dockerfile.test-runner
TARGET_DIR=${{ matrix.target_dir }} PLATFORM=${{ matrix.platform }} just test

# The date/channel/version are expected to be the same on both architectures and are needed for the merge step.
# We store them here since it makes the merge step a bit easier - it doesn't need to figure out which of the
# architectures it can run (to extract the rust version). The problem is that it appears we can't run images
# that were built by docker buildx (the build-push-action step) locally. They get pushed to dockerhub but are
# only identifiable by their digest and it appears docker does not let us select an image that way.
# Not the most elegant, but it works.
- name: Store tag info
if: ${{ steps.stablecheck.outputs.BUILD }}
shell: bash
run: |
mkdir -p /tmp/tags
RUST_DATE="$(date +"%Y-%m-%d")"
RUST_CHANNEL=stable
echo "TAG1=clux/muslrust:${RUST_CHANNEL}" >> $GITHUB_ENV
echo "TAG2=clux/muslrust:${RUST_VER}-${RUST_CHANNEL}" >> $GITHUB_ENV
echo "TAG3=clux/muslrust:${RUST_VER}" >> $GITHUB_ENV
if: ${{ steps.stablecheck.outputs.BUILD }}
RUST_VER="$(docker run --platform ${{ matrix.platform }} rustmusl-temp rustc --version | grep -oE "[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]")"

echo $RUST_DATE > /tmp/tags/rust-date
echo $RUST_CHANNEL > /tmp/tags/rust-channel
echo $RUST_VER > /tmp/tags/rust-ver

- name: Echo tags
- name: Tag and push
if: ${{ steps.stablecheck.outputs.BUILD }}
shell: bash
run: |
echo $TAG1
echo $TAG2
echo $TAG3
RUST_DATE=$(cat /tmp/tags/rust-date)
RUST_CHANNEL=$(cat /tmp/tags/rust-channel)
RUST_VER=$(cat /tmp/tags/rust-ver)

- name: Run tests
TAG_NAME="${{ matrix.arch }}-${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE}"

docker tag rustmusl-temp ${{ env.REGISTRY_IMAGE }}:$TAG_NAME
docker push ${{ env.REGISTRY_IMAGE }}:$TAG_NAME

- name: Upload tags
if: ${{ steps.stablecheck.outputs.BUILD }}
uses: actions/upload-artifact@v4
with:
name: tags
path: /tmp/tags
if-no-files-found: error
retention-days: 1
overwrite: true

merge:
name: 'Stable merge'
runs-on: ubuntu-latest
needs:
- build
steps:
- uses: 'actions/checkout@v2'
- name: Check if we need a new stable
id: stablecheck
shell: bash
run: |
pip3 install --user toml
if python3 check_stable.py; then
echo "Stable tag missing; running all build steps"
echo '::set-output name=BUILD::YES'
else
echo "Stable tag found; skipping all build steps"
fi

- name: Download tags
if: ${{ steps.stablecheck.outputs.BUILD }}
run: just test
uses: actions/download-artifact@v4
with:
path: /tmp/tags
name: tags

- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY_IMAGE }}

- name: Login to Docker Hub
uses: docker/login-action@v3
eranrund marked this conversation as resolved.
Show resolved Hide resolved
if: false
with:
username: clux
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Push image under computed tags
uses: docker/build-push-action@v3
- name: Create manifest list and push multi-platform images
if: ${{ steps.stablecheck.outputs.BUILD }}
with:
context: .
build-args: |
CHANNEL=stable
push: ${{ steps.stablecheck.outputs.BUILD == 'YES' && github.event_name != 'pull_request' }}
tags: ${{ env.TAG1 }},${{ env.TAG2 }},${{ env.TAG3 }}
run: |
RUST_DATE=$(cat /tmp/tags/rust-date)
RUST_CHANNEL=$(cat /tmp/tags/rust-channel)
RUST_VER=$(cat /tmp/tags/rust-ver)

for tag in ${RUST_CHANNEL} ${RUST_CHANNEL}-${RUST_DATE} ${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE}; do
docker buildx imagetools create -t ${{ env.REGISTRY_IMAGE }}:$tag \
${{ env.REGISTRY_IMAGE }}:amd64-${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE} \
${{ env.REGISTRY_IMAGE }}:arm64-${RUST_VER}-${RUST_CHANNEL}-${RUST_DATE}
done

- name: Inspect image
if: ${{ steps.stablecheck.outputs.BUILD }}
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:latest
Loading
Loading