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
178 changes: 76 additions & 102 deletions .github/workflows/image-build-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ name: Docker Build
on:
push:
branches:
- main # Only build and push after PR is merged to main
- main
pull_request:
branches:
- main
workflow_dispatch:
release:
types: [published, edited]

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

permissions:
contents: read
packages: write
Expand All @@ -17,6 +24,16 @@ env:
GHCR_IMAGE: ghcr.io/perun-engineering/aws-helm-kubectl

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Lint Dockerfile
uses: hadolint/hadolint-action@v3.1.0
with:
dockerfile: Dockerfile

define:
runs-on: ubuntu-latest
outputs:
Expand All @@ -27,17 +44,45 @@ jobs:
- name: Read environment file
id: read_env
run: |
# Extract only the KUBERNETES_VERSIONS line and get the array part
VERSIONS=$(grep '^KUBERNETES_VERSIONS=' .env | cut -d'=' -f2-)
echo "versions=$VERSIONS" >> $GITHUB_OUTPUT

validate:
if: github.event_name == 'pull_request'
needs: [lint, define]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Read environment file
run: cat .env >> ${GITHUB_ENV}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build (validation only)
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64
push: false
build-args: |
KUBE_VERSION=${{ fromJson(needs.define.outputs.kubernetes_versions)[0] }}
HELM_VERSION=${{ env.HELM_VERSION }}
SOPS_VERSION=${{ env.SOPS_VERSION }}
HELM_SECRETS_VERSION=${{ env.HELM_SECRETS_VERSION }}
HELM_S3_VERSION=${{ env.HELM_S3_VERSION }}
HELMFILE_VERSION=${{ env.HELMFILE_VERSION }}
AWS_CLI_VERSION=${{ env.AWS_CLI_VERSION }}
HELM_DIFF_VERSION=${{ env.HELM_DIFF_VERSION }}
ALPINE_PYTHON=${{ env.ALPINE_PYTHON }}
ALPINE_VERSION=${{ env.ALPINE_VERSION }}

build:
needs:
- define
if: github.event_name != 'pull_request'
needs: [lint, define]
strategy:
fail-fast: true
matrix:
version: ${{fromJson(needs.define.outputs.kubernetes_versions)}}
version: ${{ fromJson(needs.define.outputs.kubernetes_versions) }}
platform:
- linux/amd64
- linux/arm64
Expand All @@ -52,21 +97,13 @@ jobs:
uses: actions/checkout@v6
- name: Read environment file
run: cat .env >> ${GITHUB_ENV}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ vars.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v6
Expand All @@ -76,10 +113,9 @@ jobs:
${{ env.GHCR_IMAGE }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Build and push to Docker Hub
- name: Build and push
id: build
uses: docker/build-push-action@v6
with:
Expand All @@ -98,66 +134,29 @@ jobs:
ALPINE_PYTHON=${{ env.ALPINE_PYTHON }}
ALPINE_VERSION=${{ env.ALPINE_VERSION }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
cache-from: type=gha,scope=${{ matrix.version }}-${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.version }}-${{ matrix.platform }}

- name: Re-tag and push to GHCR
id: build-ghcr
uses: docker/build-push-action@v6
with:
context: .
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true
build-args: |
KUBE_VERSION=${{ matrix.version }}
HELM_VERSION=${{ env.HELM_VERSION }}
SOPS_VERSION=${{ env.SOPS_VERSION }}
HELM_SECRETS_VERSION=${{ env.HELM_SECRETS_VERSION }}
HELM_S3_VERSION=${{ env.HELM_S3_VERSION }}
HELMFILE_VERSION=${{ env.HELMFILE_VERSION }}
AWS_CLI_VERSION=${{ env.AWS_CLI_VERSION }}
HELM_DIFF_VERSION=${{ env.HELM_DIFF_VERSION }}
ALPINE_PYTHON=${{ env.ALPINE_PYTHON }}
ALPINE_VERSION=${{ env.ALPINE_VERSION }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha

- name: Export digest (Docker Hub)
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
echo "$digest" | sed 's/^sha256://' > "/tmp/digests/${digest#sha256:}"

- name: Export digest (GHCR)
run: |
mkdir -p /tmp/digests-ghcr
digest="${{ steps.build-ghcr.outputs.digest }}"
echo "$digest" | sed 's/^sha256://' > "/tmp/digests-ghcr/${digest#sha256:}"

- name: Upload digest (Docker Hub)
- name: Upload digest
uses: actions/upload-artifact@v7
with:
name: digests-${{ matrix.version }}-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

- name: Upload digest (GHCR)
uses: actions/upload-artifact@v7
with:
name: digests-ghcr-${{ matrix.version }}-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
path: /tmp/digests-ghcr/*
if-no-files-found: error
retention-days: 1

merge:
needs:
- define
- build
needs: [define, build]
runs-on: ubuntu-latest
strategy:
matrix:
version: ${{fromJson(needs.define.outputs.kubernetes_versions)}}
version: ${{ fromJson(needs.define.outputs.kubernetes_versions) }}
steps:
- name: Download digests
uses: actions/download-artifact@v8
Expand All @@ -175,21 +174,17 @@ jobs:
username: ${{ vars.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Create manifest list and push (Docker Hub)
- name: Create manifest list and push
run: |
# First verify the directory and files exist
ls -la /tmp/digests

# Create the manifest list
cd /tmp/digests
docker buildx imagetools create -t ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }} \
$(for digest in *; do echo -n "${{ env.DOCKERHUB_IMAGE }}@sha256:$digest "; done)

- name: Inspect image (Docker Hub)
run: |
docker buildx imagetools inspect ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }}
- name: Inspect image
run: docker buildx imagetools inspect ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }}

- name: Test final image (Docker Hub)
- name: Test final image
run: |
echo "Testing final image functionality..."
docker run --rm ${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }} /bin/bash -c "
Expand All @@ -202,55 +197,34 @@ jobs:
echo 'All tools working correctly!'
"

merge-ghcr:
needs:
- define
- build
copy-to-ghcr:
needs: [define, merge]
runs-on: ubuntu-latest
strategy:
matrix:
version: ${{fromJson(needs.define.outputs.kubernetes_versions)}}
version: ${{ fromJson(needs.define.outputs.kubernetes_versions) }}
steps:
- name: Download digests (GHCR)
uses: actions/download-artifact@v8
with:
pattern: digests-ghcr-${{ matrix.version }}-*
path: /tmp/digests-ghcr
merge-multiple: true

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

- name: Login to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ vars.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create manifest list and push (GHCR)
run: |
# First verify the directory and files exist
ls -la /tmp/digests-ghcr

# Create the manifest list
cd /tmp/digests-ghcr
docker buildx imagetools create -t ${{ env.GHCR_IMAGE }}:${{ matrix.version }} \
$(for digest in *; do echo -n "${{ env.GHCR_IMAGE }}@sha256:$digest "; done)

- name: Inspect image (GHCR)
- name: Copy manifest to GHCR
run: |
docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ matrix.version }}
docker buildx imagetools create \
-t ${{ env.GHCR_IMAGE }}:${{ matrix.version }} \
${{ env.DOCKERHUB_IMAGE }}:${{ matrix.version }}

- name: Test final image (GHCR)
run: |
echo "Testing final image functionality..."
docker run --rm ${{ env.GHCR_IMAGE }}:${{ matrix.version }} /bin/bash -c "
echo 'Testing tool versions:' &&
kubectl version --client &&
helm version &&
aws --version &&
sops --version &&
helmfile --version &&
echo 'All tools working correctly!'
"
- name: Inspect image
run: docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ matrix.version }}
31 changes: 6 additions & 25 deletions .github/workflows/pr-title.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,22 @@ jobs:
name: Validate PR title
runs-on: ubuntu-latest
steps:
# Please look up the latest version from
# https://github.com/amannn/action-semantic-pull-request/releases
- uses: amannn/action-semantic-pull-request@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Configure which types are allowed.
# Default: https://github.com/commitizen/conventional-commit-types
types: |
fix
feat
docs
ci
chore
# Configure that a scope must always be provided.
refactor
test
perf
build
revert
requireScope: false
# Configure additional validation for the subject based on a regex.
# This example ensures the subject starts with an uppercase character.
subjectPattern: ^[A-Z].+$
# If `subjectPattern` is configured, you can use this property to override
# the default error message that is shown when the pattern doesn't match.
# The variables `subject` and `title` can be used within the message.
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
starts with an uppercase character.
# For work-in-progress PRs you can typically use draft pull requests
# from Github. However, private repositories on the free plan don't have
# this option and therefore this action allows you to opt-in to using the
# special "[WIP]" prefix to indicate this state. This will avoid the
# validation of the PR title and the pull request checks remain pending.
# Note that a second check will be reported if this is enabled.
subjectPattern: ^.+$
wip: true
# When using "Squash and merge" on a PR with only one commit, GitHub
# will suggest using that commit message instead of the PR title for the
# merge commit, and it's easy to commit this by mistake. Enable this option
# to also validate the commit message for one commit PRs.
validateSingleCommit: false
10 changes: 8 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ on:
branches:
- main

concurrency:
group: release
cancel-in-progress: false

permissions:
contents: read

Expand All @@ -20,8 +24,9 @@ jobs:
pull-requests: write
name: Release
runs-on: ubuntu-latest
# Skip running release workflow on forks and only run if Docker Build succeeded
if: github.repository_owner == 'Perun-Engineering' && github.event.workflow_run.conclusion == 'success'
if: >-
github.repository_owner == 'Perun-Engineering' &&
(github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success')
steps:
- name: Checkout
uses: actions/checkout@v6
Expand All @@ -46,6 +51,7 @@ jobs:

dockerHubDescription:
runs-on: ubuntu-latest
if: github.repository_owner == 'Perun-Engineering'
steps:
- uses: actions/checkout@v6

Expand Down
Loading
Loading