-
Notifications
You must be signed in to change notification settings - Fork 0
feat: switch base image to GitHub runner and add DevOps tools #1
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
base: main
Are you sure you want to change the base?
Changes from all commits
10d0b70
51c2b52
02d7b2e
6db1c23
8c2eb93
ea59872
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| extends: | ||
| - "@commitlint/config-conventional" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| .git | ||
| .github | ||
| build | ||
| .env | ||
| *.md | ||
| LICENSE | ||
| .dive-ci | ||
| .hadolint.yaml | ||
| .releaserc.yaml | ||
| .commitlintrc.yaml | ||
| .containerignore | ||
| .pre-commit-config.yaml | ||
| scripts/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [master] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: read | ||
|
|
||
| jobs: | ||
| commitlint: | ||
| name: Lint commit messages | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - uses: wagoid/commitlint-github-action@v6 | ||
|
|
||
| hadolint: | ||
| name: Lint Containerfile | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: hadolint/hadolint-action@v3.1.0 | ||
| with: | ||
| dockerfile: Containerfile | ||
|
|
||
| build: | ||
| name: Test build | ||
| runs-on: ubuntu-latest | ||
| needs: [hadolint] | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Build image | ||
| run: docker build -f Containerfile -t test-build . | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,145 @@ | ||||||||||||||||||||||||||||||
| name: Release | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||
| push: | ||||||||||||||||||||||||||||||
| branches: [master] | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||
| packages: write | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||
| release: | ||||||||||||||||||||||||||||||
| name: Semantic release | ||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||||
| new_release_published: ${{ steps.semantic.outputs.new_release_published }} | ||||||||||||||||||||||||||||||
| new_release_version: ${{ steps.semantic.outputs.new_release_version }} | ||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| persist-credentials: false | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - uses: cycjimmy/semantic-release-action@v4 | ||||||||||||||||||||||||||||||
| id: semantic | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| extra_plugins: | | ||||||||||||||||||||||||||||||
| @semantic-release/changelog | ||||||||||||||||||||||||||||||
| @semantic-release/git | ||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| build-and-push: | ||||||||||||||||||||||||||||||
| name: Build, scan & push | ||||||||||||||||||||||||||||||
| needs: release | ||||||||||||||||||||||||||||||
| if: needs.release.outputs.new_release_published == 'true' | ||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||
| IMAGE_VERSION: ${{ needs.release.outputs.new_release_version }} | ||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Install build tools | ||||||||||||||||||||||||||||||
| run: ./scripts/install_tools.sh | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Read manifest | ||||||||||||||||||||||||||||||
| id: manifest | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| echo "image_name=$(yq e '.name' manifest.yaml)" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||||||||||
| echo "registry=$(yq e '.registry' manifest.yaml)" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||||||||||
| echo "format=$(yq e '.build.format' manifest.yaml)" >> "$GITHUB_OUTPUT" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Validate Containerfile | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| docker pull -q ghcr.io/hadolint/hadolint:latest | ||||||||||||||||||||||||||||||
| docker run --rm -i hadolint/hadolint:latest < Containerfile | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
| docker run --rm -i hadolint/hadolint:latest < Containerfile | |
| docker run --rm -i -v "${PWD}/.hadolint.yaml:/.hadolint.yaml" hadolint/hadolint:latest --config /.hadolint.yaml < Containerfile |
Copilot
AI
Feb 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dive scan expects the image to be loaded into the Docker daemon, but the load command on line 98 uses 2>/dev/null || true which silently ignores all errors. If the OCI archive is corrupted or incompatible, the load will fail silently, and the subsequent docker tag on line 99 will also fail silently. This means the dive scan on line 104 will fail with a confusing error about the image not being found. Remove the || true or add explicit error checking to ensure the image is successfully loaded before attempting to scan it.
| docker load -i "build/${IMAGE_NAME}.tar" 2>/dev/null || true | |
| docker tag "$(docker images -q | head -1)" "${IMAGE_NAME}:${IMAGE_VERSION}" 2>/dev/null || true | |
| docker load -i "build/${IMAGE_NAME}.tar" | |
| docker tag "$(docker images -q | head -1)" "${IMAGE_NAME}:${IMAGE_VERSION}" |
Copilot
AI
Feb 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version parsing logic assumes semantic versioning with at least two dots (MAJOR.MINOR.PATCH format). If the release version is "1.0" instead of "1.0.0", the MAJOR_MINOR variable on line 126 will be "1" (same as MAJOR), and MAJOR on line 127 will be empty, causing the subsequent skopeo copy commands to fail or push to incorrect tags. Add validation to ensure the version has the expected format, or make the parsing more robust to handle version strings with fewer components.
| MAJOR_MINOR="${IMAGE_VERSION%.*}" | |
| MAJOR="${IMAGE_VERSION%%.*}" | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$IMAGE_VERSION" | |
| if [ -z "$MAJOR" ]; then | |
| echo "ERROR: Failed to parse IMAGE_VERSION '$IMAGE_VERSION' into a major version component." >&2 | |
| exit 1 | |
| fi | |
| if [ -n "$MINOR" ]; then | |
| MAJOR_MINOR="${MAJOR}.${MINOR}" | |
| else | |
| MAJOR_MINOR="${MAJOR}" | |
| fi |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,132 @@ | ||||||||||||||||||
| name: Update tool versions | ||||||||||||||||||
|
|
||||||||||||||||||
| on: | ||||||||||||||||||
| schedule: | ||||||||||||||||||
| - cron: "0 8 * * 1" # Every Monday at 08:00 UTC | ||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||
|
|
||||||||||||||||||
| permissions: | ||||||||||||||||||
| contents: write | ||||||||||||||||||
| pull-requests: write | ||||||||||||||||||
|
|
||||||||||||||||||
| jobs: | ||||||||||||||||||
| update-tools: | ||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||
| steps: | ||||||||||||||||||
| - name: Checkout | ||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Fetch latest tool versions | ||||||||||||||||||
| id: versions | ||||||||||||||||||
| env: | ||||||||||||||||||
| GH_TOKEN: ${{ github.token }} | ||||||||||||||||||
| run: | | ||||||||||||||||||
| get_latest_version() { | ||||||||||||||||||
| local repo="$1" | ||||||||||||||||||
| gh api "repos/${repo}/releases/latest" --jq '.tag_name' | sed 's/^v//' | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| ARGO_LATEST=$(get_latest_version "argoproj/argo-workflows") | ||||||||||||||||||
| KARGO_LATEST=$(get_latest_version "akuity/kargo") | ||||||||||||||||||
| PACK_LATEST=$(get_latest_version "buildpacks/pack") | ||||||||||||||||||
| DIVE_LATEST=$(get_latest_version "wagoodman/dive") | ||||||||||||||||||
| HADOLINT_LATEST=$(get_latest_version "hadolint/hadolint") | ||||||||||||||||||
| YQ_LATEST=$(get_latest_version "mikefarah/yq") | ||||||||||||||||||
|
|
||||||||||||||||||
| echo "argo=${ARGO_LATEST}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "kargo=${KARGO_LATEST}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "pack=${PACK_LATEST}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "dive=${DIVE_LATEST}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "hadolint=${HADOLINT_LATEST}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "yq=${YQ_LATEST}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
|
|
||||||||||||||||||
| ARGO_CURRENT=$(grep -oP 'ARGO_VERSION=\K[0-9.]+' Containerfile) | ||||||||||||||||||
| KARGO_CURRENT=$(grep -oP 'KARGO_VERSION=\K[0-9.]+' Containerfile) | ||||||||||||||||||
| PACK_CURRENT=$(grep -oP 'PACK_VERSION=\K[0-9.]+' Containerfile) | ||||||||||||||||||
| DIVE_CURRENT=$(grep -oP 'DIVE_VERSION=\K[0-9.]+' Containerfile) | ||||||||||||||||||
| HADOLINT_CURRENT=$(grep -oP 'HADOLINT_VERSION=\K[0-9.]+' Containerfile) | ||||||||||||||||||
| YQ_CURRENT=$(grep -oP 'YQ_VERSION=\K[0-9.]+' Containerfile) | ||||||||||||||||||
|
|
||||||||||||||||||
| echo "argo_current=${ARGO_CURRENT}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "kargo_current=${KARGO_CURRENT}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "pack_current=${PACK_CURRENT}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "dive_current=${DIVE_CURRENT}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "hadolint_current=${HADOLINT_CURRENT}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "yq_current=${YQ_CURRENT}" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
|
|
||||||||||||||||||
| UPDATES="" | ||||||||||||||||||
| if [ "${ARGO_CURRENT}" != "${ARGO_LATEST}" ]; then | ||||||||||||||||||
| UPDATES="${UPDATES}- Argo Workflows CLI: ${ARGO_CURRENT} -> ${ARGO_LATEST}\n" | ||||||||||||||||||
| fi | ||||||||||||||||||
| if [ "${KARGO_CURRENT}" != "${KARGO_LATEST}" ]; then | ||||||||||||||||||
| UPDATES="${UPDATES}- Kargo CLI: ${KARGO_CURRENT} -> ${KARGO_LATEST}\n" | ||||||||||||||||||
| fi | ||||||||||||||||||
| if [ "${PACK_CURRENT}" != "${PACK_LATEST}" ]; then | ||||||||||||||||||
| UPDATES="${UPDATES}- pack (Buildpacks): ${PACK_CURRENT} -> ${PACK_LATEST}\n" | ||||||||||||||||||
| fi | ||||||||||||||||||
| if [ "${DIVE_CURRENT}" != "${DIVE_LATEST}" ]; then | ||||||||||||||||||
| UPDATES="${UPDATES}- dive: ${DIVE_CURRENT} -> ${DIVE_LATEST}\n" | ||||||||||||||||||
| fi | ||||||||||||||||||
| if [ "${HADOLINT_CURRENT}" != "${HADOLINT_LATEST}" ]; then | ||||||||||||||||||
| UPDATES="${UPDATES}- hadolint: ${HADOLINT_CURRENT} -> ${HADOLINT_LATEST}\n" | ||||||||||||||||||
| fi | ||||||||||||||||||
| if [ "${YQ_CURRENT}" != "${YQ_LATEST}" ]; then | ||||||||||||||||||
| UPDATES="${UPDATES}- yq: ${YQ_CURRENT} -> ${YQ_LATEST}\n" | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ -z "${UPDATES}" ]; then | ||||||||||||||||||
| echo "has_updates=false" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo "No updates found." | ||||||||||||||||||
| else | ||||||||||||||||||
| echo "has_updates=true" >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| # Use a delimiter for multiline output | ||||||||||||||||||
| { | ||||||||||||||||||
| echo "summary<<EOF" | ||||||||||||||||||
| echo -e "${UPDATES}" | ||||||||||||||||||
| echo "EOF" | ||||||||||||||||||
| } >> "$GITHUB_OUTPUT" | ||||||||||||||||||
| echo -e "Updates found:\n${UPDATES}" | ||||||||||||||||||
| fi | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Update versions in Containerfile and manifest | ||||||||||||||||||
| if: steps.versions.outputs.has_updates == 'true' | ||||||||||||||||||
| env: | ||||||||||||||||||
| ARGO_LATEST: ${{ steps.versions.outputs.argo }} | ||||||||||||||||||
| KARGO_LATEST: ${{ steps.versions.outputs.kargo }} | ||||||||||||||||||
| PACK_LATEST: ${{ steps.versions.outputs.pack }} | ||||||||||||||||||
| DIVE_LATEST: ${{ steps.versions.outputs.dive }} | ||||||||||||||||||
| HADOLINT_LATEST: ${{ steps.versions.outputs.hadolint }} | ||||||||||||||||||
| YQ_LATEST: ${{ steps.versions.outputs.yq }} | ||||||||||||||||||
| ARGO_CURRENT: ${{ steps.versions.outputs.argo_current }} | ||||||||||||||||||
| KARGO_CURRENT: ${{ steps.versions.outputs.kargo_current }} | ||||||||||||||||||
| PACK_CURRENT: ${{ steps.versions.outputs.pack_current }} | ||||||||||||||||||
| DIVE_CURRENT: ${{ steps.versions.outputs.dive_current }} | ||||||||||||||||||
| HADOLINT_CURRENT: ${{ steps.versions.outputs.hadolint_current }} | ||||||||||||||||||
| YQ_CURRENT: ${{ steps.versions.outputs.yq_current }} | ||||||||||||||||||
| run: | | ||||||||||||||||||
| update_version() { | ||||||||||||||||||
| local name="$1" current="$2" latest="$3" | ||||||||||||||||||
| if [ "${current}" != "${latest}" ]; then | ||||||||||||||||||
| sed -i "s/${name}=${current}/${name}=${latest}/g" Containerfile manifest.yaml | ||||||||||||||||||
|
||||||||||||||||||
| sed -i "s/${name}=${current}/${name}=${latest}/g" Containerfile manifest.yaml | |
| # Update ARG declaration in Containerfile, e.g.: | |
| # ARG ARGO_VERSION=1.2.3 | |
| sed -i -E "s/^(ARG ${name}=)${current}$/\1${latest}/" Containerfile | |
| # Update YAML key in manifest.yaml, e.g.: | |
| # ARGO_VERSION: 1.2.3 | |
| sed -i -E "s/^([[:space:]]*${name}:[[:space:]]*)${current}/\1${latest}/" manifest.yaml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| trustedRegistries: | ||
| - docker.io | ||
| - ghcr.io |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,30 @@ | ||||
| repos: | ||||
| - repo: https://github.com/pre-commit/pre-commit-hooks | ||||
| rev: v5.0.0 | ||||
| hooks: | ||||
| - id: trailing-whitespace | ||||
| - id: end-of-file-fixer | ||||
| - id: check-yaml | ||||
| - id: check-added-large-files | ||||
| - id: check-merge-conflict | ||||
| - id: detect-private-key | ||||
|
|
||||
| - repo: https://github.com/hadolint/hadolint | ||||
| rev: v2.12.0 | ||||
| hooks: | ||||
| - id: hadolint-docker | ||||
| entry: hadolint/hadolint hadolint | ||||
|
||||
| entry: hadolint/hadolint hadolint |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| branches: | ||
| - master | ||
|
|
||
| plugins: | ||
| - "@semantic-release/commit-analyzer" | ||
| - "@semantic-release/release-notes-generator" | ||
| - - "@semantic-release/changelog" | ||
| - changelogFile: CHANGELOG.md | ||
| - - "@semantic-release/github" | ||
| - assets: [] | ||
| - - "@semantic-release/git" | ||
| - assets: | ||
| - CHANGELOG.md | ||
| message: "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CI workflow's test build uses
docker buildwhich doesn't pass any of the build args defined in manifest.yaml (RUNNER_VERSION, ARGO_VERSION, etc.). This means the test build won't accurately reflect the actual build process used in the release workflow, potentially missing build failures related to these arguments. Consider using the same build approach as release.yaml or at least passing the build args from manifest.yaml.