Skip to content

add annotations to container image #19

add annotations to container image

add annotations to container image #19

Workflow file for this run

name: 'CI/CD'
on:
pull_request:
push:
branches:
- canary
- main
env:
APP_NAME: fosdem-dl
GRAALVM_VERSION: 23.0.0
HEAP_SIZE_AT_BUILD_TIME: '-R:MaximumHeapSizePercent=50'
JAVA_VERSION: 21
OPTIMIZATION_LEVEL: '-O2'
jobs:
shared-outputs:
name: Shared outputs
runs-on: ubuntu-latest
outputs:
app_version: ${{ steps.set_outputs.outputs.app_version }}
is_prerelease: ${{ steps.set_outputs.outputs.is_prerelease }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup Babashka
uses: DeLaGuardo/[email protected]
with:
bb: 'latest'
# Note: if in bb.edn we declare a version of a pod using :path instead of
# :version (e.g. we have to do this when the pod is not registered on the
# pod registry), we can't run Babashka commands until we have downloaded
# that pod manually and moved it to the :path specified in bb.edn.
- name: Set job outputs
id: set_outputs
run: |
APP_VERSION=$(bb -e '(-> (slurp "deps.edn") edn/read-string :aliases :neil :project :version)' | tr -d '"')
echo "app_version=$APP_VERSION" >> $GITHUB_OUTPUT
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "is_prerelease=false" >> $GITHUB_OUTPUT
else
echo "is_prerelease=true" >> $GITHUB_OUTPUT
fi
- name: Log job outputs
run: |
echo "app_version is ${{ steps.set_outputs.outputs.app_version }}"
echo "is_prerelease is ${{ steps.set_outputs.outputs.is_prerelease }}"
# echo "pod_jackdbd_jsoup_path_linux is ${{ steps.set_outputs.outputs.pod_jackdbd_jsoup_path_linux }}"
# echo "pod_jackdbd_jsoup_path_macos is ${{ steps.set_outputs.outputs.pod_jackdbd_jsoup_path_macos }}"
uberjar:
name: Uberjar
needs: [shared-outputs]
runs-on: ubuntu-latest
env:
APP_VERSION: ${{ needs.shared-outputs.outputs.app_version }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup Clojure CLI and Babashka
uses: DeLaGuardo/[email protected]
with:
cli: 'latest'
bb: 'latest'
# Downloading the pod manually is only necessary if in bb.edn we declare
# the pod with :path instead of :version (e.g. when we want a version of
# the pod that is not registered on pod registry).
# This action uses the GitHub CLI.
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/using-github-cli-in-workflows
# - name: ⬇️ Download com.github.jackdbd/pod-jackdbd-jsoup
# env:
# GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# run: ./download_pod_jackdbd_jsoup.sh
- name: 📦 Build a Babashka uberjar
run: bb build:bb-uber
- name: "CLI talks --help"
run: bb target/${{env.APP_NAME }}-${{ env.APP_VERSION }}.jar talks --help
- name: "CLI tracks --help"
run: bb target/${{env.APP_NAME }}-${{ env.APP_VERSION }}.jar tracks --help
- name: ⬆️ Upload Babashka uberjar
uses: actions/upload-artifact@v4
with:
name: bb-uberjar
path: target/${{ env.APP_NAME }}-${{ env.APP_VERSION }}.jar
if-no-files-found: error
- name: 📦 Build normal uberjar
run: |
clojure -T:build clean
clojure -T:build uber
- name: ⬆️ Upload uberjar
uses: actions/upload-artifact@v4
with:
name: uberjar
path: target/${{ env.APP_NAME }}-${{ env.APP_VERSION }}-standalone.jar
if-no-files-found: error
test:
name: Test
needs: []
runs-on: ubuntu-latest
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup Babashka
uses: DeLaGuardo/[email protected]
with:
bb: 'latest'
- name: 🔍 Run all tests
run: bb test_runner.clj
# https://github.com/liquidz/babashka-test-action/
# - name: Run babashka-test-action
# uses: liquidz/babashka-test-action@v1
# with:
# source-paths: 'src'
# test-paths: 'test'
# test-file-pattern: '_test.clj$'
container-image:
name: Container image
needs: [shared-outputs]
runs-on: ubuntu-latest
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
APP_VERSION: ${{ needs.shared-outputs.outputs.app_version }}
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
# - name: 🔧 Setup Clojure CLI and Babashka
# uses: DeLaGuardo/[email protected]
# with:
# cli: 'latest'
# bb: 'latest'
# - name: 🐋 Build container image
# run: bb container:build
# # Print a few commands to double check that the CLI is working as expected
# - run: bb container:cli help
# - run: bb container:cli talks --help
# - run: bb container:cli tracks --help
# https://github.com/marketplace/actions/docker-login
- name: Log in to the Container registry
uses: docker/[email protected]
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# https://github.com/marketplace/actions/docker-metadata-action
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/[email protected]
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
annotations: |
org.opencontainers.image.revision=${{ github.sha }}
# I don't know how to tell docker-metadata-action to extract the
# license, so I set it here explicitly.
# https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/
labels: |
org.opencontainers.image.description="CLI to download videos and slides from FOSDEM websites"
org.opencontainers.image.documentation=https://github.com/jackdbd/fosdem-dl/
org.opencontainers.image.licenses=MIT
# https://github.com/marketplace/actions/build-and-push-docker-images
- name: Build and push Docker image
id: push
uses: docker/[email protected]
with:
context: .
push: true
build-args: |
APP_NAME=${{env.APP_NAME }}
APP_VERSION=${{env.APP_VERSION }}
BB_VERSION=1.4.192
CREATED_DATE=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
JSOUP_POD_VERSION=0.4.0
annotations: ${{ steps.meta.outputs.annotations }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
# https://github.com/marketplace/actions/attest-build-provenance
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
linux-amd64-binary:
name: Linux amd64 binary
needs: [shared-outputs, uberjar]
runs-on: ubuntu-latest
env:
APP_VERSION: ${{ needs.shared-outputs.outputs.app_version }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup GraalVM
uses: graalvm/setup-graalvm@v1
with:
check-for-updates: true
distribution: graalvm-community
java-version: ${{ env.JAVA_VERSION }}
native-image-job-reports: true
native-image-musl: true # Use musl to build a statically compiled binary (Linux only)
native-image-pr-reports: true
version: ${{ env.GRAALVM_VERSION }}
- name: 🔧 Setup Babashka
uses: DeLaGuardo/[email protected]
with:
bb: 'latest'
# Calling `bb tasks` is enough to let Babashka download all pods declared
# in the bb.edn file. Babashka downloads only the pod binary files that
# were compiled for the combination of OS & arch of this GitHub runner.
- run: bb tasks
- name: ⬇️ Download uberjar
uses: actions/download-artifact@v4
with:
name: uberjar
- name: Move uberjar to target/
run: |
mkdir target
mv ${{ env.APP_NAME }}-${{ env.APP_VERSION }}-standalone.jar target/
# Troubleshooting: Babashka pods should be somewhere here.
# - run: ls -1 -R ~/.babashka
- name: 📦 Compile uberjar to x86_64-linux binary with GraalVM native-image
run: ./script/compile.sh
- run: ls -1 -R
- name: ⬆️ Upload Linux amd64 binary
uses: actions/upload-artifact@v4
with:
name: linux-amd64-binary
path: ${{ env.APP_NAME }}
if-no-files-found: error
macos-aarch64-binary:
name: macOS aarch64 binary
needs: [shared-outputs, uberjar]
runs-on: macos-latest
env:
APP_VERSION: ${{ needs.shared-outputs.outputs.app_version }}
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: 🔧 Setup GraalVM
uses: graalvm/setup-graalvm@v1
with:
check-for-updates: true
distribution: graalvm-community
java-version: ${{ env.JAVA_VERSION }}
native-image-job-reports: true
native-image-pr-reports: true
version: ${{ env.GRAALVM_VERSION }}
- name: 🔧 Setup Babashka
uses: DeLaGuardo/[email protected]
with:
bb: 'latest'
# We let Babashka download the pod for this OS & architecture.
- run: bb tasks
# - run: ls -1 -R ~/.babashka
- name: ⬇️ Download uberjar
uses: actions/download-artifact@v4
with:
name: uberjar
# TODO: bundle pod-jackdbd-jsoup when building with GraalVM native-image
- name: 📦 Compile uberjar to AArch64-macOS binary with GraalVM native-image
run: |
native-image -jar ${{ env.APP_NAME }}-${{ env.APP_VERSION }}-standalone.jar ${{ env.APP_NAME }} \
'-H:ResourceConfigurationFiles=resource-config.json' \
'-H:+UnlockExperimentalVMOptions' \
'--gc=serial' \
${{ env.HEAP_SIZE_AT_BUILD_TIME }} \
${{ env.OPTIMIZATION_LEVEL }} \
'-march=armv8-a' \
'--initialize-at-run-time=fosdem_dl.cli' \
'--native-image-info' \
'--no-fallback' \
'--verbose'
- name: ⬆️ Upload macOS aarch64 binary
uses: actions/upload-artifact@v4
with:
name: macos-aarch64-binary
path: ${{ env.APP_NAME }}
if-no-files-found: error
github-release:
name: GitHub release
if: ${{ github.event_name != 'pull_request' }}
needs: [shared-outputs, uberjar, container-image, linux-amd64-binary, macos-aarch64-binary]
runs-on: ubuntu-latest
env:
APP_VERSION: ${{ needs.shared-outputs.outputs.app_version }}
IS_PRERELEASE: ${{ needs.shared-outputs.outputs.is_prerelease }}
permissions:
contents: write
steps:
- name: 🛎️ Checkout
uses: actions/checkout@v4
- name: ⬇️ Download uberjar
uses: actions/download-artifact@v4
with:
name: uberjar
- name: ⬇️ Download bb-uberjar
uses: actions/download-artifact@v4
with:
name: bb-uberjar
- name: ⬇️ Download linux-amd64-binary
uses: actions/download-artifact@v4
with:
name: linux-amd64-binary
- run: mv fosdem-dl linux-amd64-binary
- name: ⬇️ Download macos-aarch64-binary
uses: actions/download-artifact@v4
with:
name: macos-aarch64-binary
- run: mv fosdem-dl macos-aarch64-binary
- name: 📦 Create archives for all assets to be included in the GitHub release
run: |
mv linux-amd64-binary fosdem-dl && zip "${{ env.APP_NAME }}-${{ env.APP_VERSION }}-linux-amd64.zip" fosdem-dl && rm fosdem-dl
mv macos-aarch64-binary fosdem-dl && zip "${{ env.APP_NAME }}-${{ env.APP_VERSION }}-macos-aarch64.zip" fosdem-dl && rm fosdem-dl
# Troubleshooting: do we have every assets we want to include in the GitHub release?
- run: ls -la
# https://github.com/marketplace/actions/gh-release
- name: Add uberjar to GitHub release
uses: softprops/action-gh-release@v2
id: github_release
with:
body_path: ${{ github.workspace }}/docs/release-body.md
# draft: true
fail_on_unmatched_files: true
# TODO: add all binaries compiled with GraalVM native-image
files: |
${{ env.APP_NAME }}-${{ env.APP_VERSION }}.jar
${{ env.APP_NAME }}-${{ env.APP_VERSION }}-standalone.jar
${{ env.APP_NAME }}-${{ env.APP_VERSION }}-linux-amd64.zip
${{ env.APP_NAME }}-${{ env.APP_VERSION }}-macos-aarch64.zip
# body is prepended to these automatically generated release notes.
# See here for how to configure these release notes:
# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes
generate_release_notes: true
name: v${{ env.APP_VERSION }}
prerelease: ${{ env.IS_PRERELEASE }}
tag_name: v${{ env.APP_VERSION }}