Skip to content
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
2 changes: 1 addition & 1 deletion .Rprofile
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ options(
)
)

.libPaths(sprintf("/root/R/x86_64-pc-linux-gnu-library/%s.%s", R.version$major, R.version$minor))
.libPaths(sprintf("/root/R/%s-library/%s.%s", R.version$platform, R.version$major, R.version$minor))
89 changes: 89 additions & 0 deletions .github/actions/docker-build-by-digest/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: 'Docker Build (Push by Digest)'
description: 'Build a Docker image for one platform and push it by digest to Docker Hub and GHCR. Output the digest for later manifest assembly.'

inputs:
image_name_dockerhub:
description: 'Docker Hub image (e.g., docker.io/sebffischer/anvl-cpu)'
required: true
image_name_ghcr:
description: 'GHCR image (e.g., ghcr.io/r-xla/anvl-cpu)'
required: true
dockerfile:
description: 'Path to the Dockerfile'
required: true
platform:
description: 'Target platform (e.g., linux/amd64)'
required: true
push:
description: 'Whether to push'
required: true
default: 'false'
dockerhub_username:
required: false
dockerhub_token:
required: false
ghcr_token:
required: false
anvl_ref:
description: 'Git ref for r-xla/anvl to install'
required: false
default: ''
no_cache:
required: false
default: 'false'
github_pat:
description: 'Token passed as a Docker build secret for private repo access'
required: false
default: ''

outputs:
digest:
description: 'Image digest pushed by this build'
value: ${{ steps.build.outputs.digest }}

runs:
using: 'composite'
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
if: inputs.push == 'true'
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ inputs.dockerhub_username }}
password: ${{ inputs.dockerhub_token }}

- name: Log in to GitHub Container Registry
if: inputs.push == 'true'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ inputs.ghcr_token }}

- name: Compute platform pair
id: pair
shell: bash
run: |
platform="${{ inputs.platform }}"
echo "pair=${platform//\//-}" >> "$GITHUB_OUTPUT"

- name: Build and push by digest
id: build
uses: docker/build-push-action@v5
with:
context: .
file: ${{ inputs.dockerfile }}
platforms: ${{ inputs.platform }}
build-args: |
BUILDKIT_INLINE_CACHE=1
CACHEBUST=${{ github.run_id }}
ANVL_REF=${{ inputs.anvl_ref }}
secrets: ${{ inputs.github_pat != '' && format('github_pat={0}', inputs.github_pat) || '' }}
no-cache: ${{ inputs.no_cache == 'true' }}
cache-from: ${{ inputs.no_cache != 'true' && format('type=registry,ref={0}:buildcache-{1}', inputs.image_name_dockerhub, steps.pair.outputs.pair) || '' }}
cache-to: ${{ inputs.push == 'true' && format('type=registry,ref={0}:buildcache-{1},image-manifest=true', inputs.image_name_dockerhub, steps.pair.outputs.pair) || '' }}
outputs: |
type=image,"name=${{ inputs.image_name_dockerhub }},${{ inputs.image_name_ghcr }}",push-by-digest=true,name-canonical=true,push=${{ inputs.push }}
66 changes: 66 additions & 0 deletions .github/actions/docker-merge/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: 'Docker Merge Manifest'
description: 'Combine per-platform digests into a multi-arch manifest list and publish under a tag in both Docker Hub and GHCR.'

inputs:
image_name_dockerhub:
description: 'Docker Hub image (e.g., docker.io/sebffischer/anvl-cpu)'
required: true
image_name_ghcr:
description: 'GHCR image (e.g., ghcr.io/r-xla/anvl-cpu)'
required: true
tag:
description: 'Tag to publish (e.g., latest, release)'
required: true
digests_dir:
description: 'Directory containing per-platform digest files (filename = digest hex without sha256: prefix)'
required: true
dockerhub_username:
required: true
dockerhub_token:
required: true
ghcr_token:
required: true

runs:
using: 'composite'
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ inputs.dockerhub_username }}
password: ${{ inputs.dockerhub_token }}

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ inputs.ghcr_token }}

- name: Create manifest list (Docker Hub)
shell: bash
working-directory: ${{ inputs.digests_dir }}
run: |
docker buildx imagetools create \
-t "${{ inputs.image_name_dockerhub }}:${{ inputs.tag }}" \
$(printf '${{ inputs.image_name_dockerhub }}@sha256:%s ' *)

- name: Create manifest list (GHCR)
shell: bash
working-directory: ${{ inputs.digests_dir }}
run: |
docker buildx imagetools create \
-t "${{ inputs.image_name_ghcr }}:${{ inputs.tag }}" \
$(printf '${{ inputs.image_name_ghcr }}@sha256:%s ' *)

- name: Inspect (Docker Hub)
shell: bash
run: docker buildx imagetools inspect "${{ inputs.image_name_dockerhub }}:${{ inputs.tag }}"

- name: Inspect (GHCR)
shell: bash
run: docker buildx imagetools inspect "${{ inputs.image_name_ghcr }}:${{ inputs.tag }}"
134 changes: 122 additions & 12 deletions .github/workflows/cpu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
branches:
- main

env:
IMAGE_DOCKERHUB: docker.io/sebffischer/anvl-cpu
IMAGE_GHCR: ghcr.io/r-xla/anvl-cpu

jobs:
resolve-anvl-release:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -45,44 +49,150 @@ jobs:
fi

build-latest:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/docker-build
- id: build
uses: ./.github/actions/docker-build-by-digest
with:
image_name: sebffischer/anvl-cpu
image_name_dockerhub: ${{ env.IMAGE_DOCKERHUB }}
image_name_ghcr: ${{ env.IMAGE_GHCR }}
dockerfile: ./cpu/Dockerfile
platform: ${{ matrix.platform }}
push: ${{ github.event_name != 'pull_request' }}
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
ghcr_token: ${{ secrets.GITHUB_TOKEN }}
github_pat: ${{ secrets.GITHUB_TOKEN }}
extra_tags: |
docker.io/sebffischer/anvl-cpu:latest
ghcr.io/${{ github.repository_owner }}/anvl-cpu:latest
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Compute platform pair
if: github.event_name != 'pull_request'
id: pair
run: |
platform="${{ matrix.platform }}"
echo "pair=${platform//\//-}" >> "$GITHUB_OUTPUT"
- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: digests-latest-${{ steps.pair.outputs.pair }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge-latest:
needs: build-latest
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-latest-*
merge-multiple: true
- uses: ./.github/actions/docker-merge
with:
image_name_dockerhub: ${{ env.IMAGE_DOCKERHUB }}
image_name_ghcr: ${{ env.IMAGE_GHCR }}
tag: latest
digests_dir: /tmp/digests
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
ghcr_token: ${{ secrets.GITHUB_TOKEN }}

build-release:
needs: resolve-anvl-release
if: needs.resolve-anvl-release.outputs.changed == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/docker-build
- id: build
uses: ./.github/actions/docker-build-by-digest
with:
image_name: sebffischer/anvl-cpu
image_name_dockerhub: ${{ env.IMAGE_DOCKERHUB }}
image_name_ghcr: ${{ env.IMAGE_GHCR }}
dockerfile: ./cpu/Dockerfile
platform: ${{ matrix.platform }}
push: ${{ github.event_name != 'pull_request' }}
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
ghcr_token: ${{ secrets.GITHUB_TOKEN }}
github_pat: ${{ secrets.GITHUB_TOKEN }}
anvl_ref: ${{ needs.resolve-anvl-release.outputs.tag }}
extra_tags: |
docker.io/sebffischer/anvl-cpu:release
ghcr.io/${{ github.repository_owner }}/anvl-cpu:release
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Compute platform pair
if: github.event_name != 'pull_request'
id: pair
run: |
platform="${{ matrix.platform }}"
echo "pair=${platform//\//-}" >> "$GITHUB_OUTPUT"
- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: digests-release-${{ steps.pair.outputs.pair }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge-release:
needs: build-release
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-release-*
merge-multiple: true
- uses: ./.github/actions/docker-merge
with:
image_name_dockerhub: ${{ env.IMAGE_DOCKERHUB }}
image_name_ghcr: ${{ env.IMAGE_GHCR }}
tag: release
digests_dir: /tmp/digests
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
ghcr_token: ${{ secrets.GITHUB_TOKEN }}
Loading