Skip to content

Commit 1001e88

Browse files
committed
Initial commit
0 parents  commit 1001e88

7 files changed

Lines changed: 483 additions & 0 deletions

File tree

.github/workflows/build-push.yml

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Source: https://github.com/panubo/reference-github-actions/blob/main/docker-images/build-push.yml
2+
#
3+
# Description: Panubo build and push to Quay.io and ECR Public
4+
# This GH Action is intended for public docker images that package upstream applications/services (ie not for projects of Panubo's).
5+
# For repos that build multiple repos use the multi-build-push.yml workflow.
6+
#
7+
# This workflow runs on pushes to "main", PRs (does not push) or matching git tags.
8+
# Image names are generated from the repository name, if "docker-" is part of the repository name it is removed from the docker image name.
9+
#
10+
# Additionally this workflow performs some automated testing after a docker build.
11+
# Automated testing is triggered by `make _ci_test`, if no test is required the Makefile target should just run `true`.
12+
# Before tests are run a Docker build is performed, the resulting image has a tag of "test"
13+
# BATS is installed since it is commonly required by the tests.
14+
#
15+
# LICENSE: MIT License, Copyright (c) 2021-2025 Volt Grid Pty Ltd t/a Panubo
16+
17+
name: build and push on main and tags
18+
19+
on:
20+
push:
21+
branches:
22+
- main
23+
tags:
24+
- v[0-9]+.[0-9]+.[0-9]+*
25+
pull_request:
26+
27+
env:
28+
GITHUB_ROLE_ARN: arn:aws:iam::461800378586:role/GitHubECRPublic
29+
30+
permissions:
31+
id-token: write # Required for OIDC
32+
contents: read # This is required for actions/checkout
33+
34+
jobs:
35+
build_and_push:
36+
37+
runs-on: ubuntu-latest
38+
steps:
39+
- name: Checkout
40+
uses: actions/checkout@v5
41+
with:
42+
submodules: true
43+
44+
- name: Get repo name
45+
id: image_name
46+
run: |
47+
sed -E -e 's/docker-//' -e 's/^/image_name=/' <<<"${{ github.repository }}" >> "$GITHUB_OUTPUT"
48+
49+
- name: Docker meta
50+
id: meta
51+
uses: docker/metadata-action@v5
52+
with:
53+
# list of Docker images to use as base name for tags
54+
images: |
55+
quay.io/${{ steps.image_name.outputs.image_name }}
56+
public.ecr.aws/${{ steps.image_name.outputs.image_name }}
57+
# generate Docker tags based on the following events/attributes
58+
tags: |
59+
# type=schedule
60+
type=ref,event=branch
61+
type=ref,event=pr
62+
type=semver,pattern={{version}}
63+
type=semver,pattern={{major}}.{{minor}}
64+
type=match,pattern=v(.*),group=1
65+
# type=sha
66+
67+
- name: Set up QEMU
68+
uses: docker/setup-qemu-action@v3
69+
70+
- name: Set up Docker Buildx
71+
id: buildx
72+
uses: docker/setup-buildx-action@v3
73+
74+
# The values provided to these two AWS steps are always the same for Panubo owned repos
75+
- name: Configure AWS Credentials
76+
uses: aws-actions/configure-aws-credentials@v4
77+
with:
78+
role-to-assume: ${{ env.GITHUB_ROLE_ARN }}
79+
aws-region: us-east-1
80+
81+
- name: Login to ECR
82+
if: github.event_name != 'pull_request'
83+
uses: docker/login-action@v3
84+
with:
85+
registry: public.ecr.aws
86+
87+
- name: Login to Quay.io
88+
if: github.event_name != 'pull_request'
89+
uses: docker/login-action@v3
90+
with:
91+
registry: quay.io
92+
username: ${{ secrets.PANUBUILD_QUAYIO_USERNAME }}
93+
password: ${{ secrets.PANUBUILD_QUAYIO_TOKEN }}
94+
95+
- name: Setup BATS
96+
uses: bats-core/bats-action@3.0.1
97+
98+
- name: Build and export to Docker
99+
uses: docker/build-push-action@v6
100+
with:
101+
builder: ${{ steps.buildx.outputs.name }}
102+
cache-from: type=gha
103+
load: true
104+
tags: ${{ steps.image_name.outputs.image_name }}:test
105+
106+
- name: Test
107+
run: |
108+
make _ci_test
109+
110+
- name: Build and Push
111+
uses: docker/build-push-action@v6
112+
with:
113+
builder: ${{ steps.buildx.outputs.name }}
114+
push: ${{ github.event_name != 'pull_request' }}
115+
cache-from: type=gha
116+
cache-to: type=gha,mode=max
117+
platforms: linux/amd64,linux/arm64
118+
tags: ${{ steps.meta.outputs.tags }}
119+
labels: ${{ steps.meta.outputs.labels }}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Source: https://github.com/panubo/reference-github-actions/blob/main/github-release.yml
2+
# Description: Create a GitHub release
3+
# LICENSE: MIT License, Copyright (c) 2021-2025 Volt Grid Pty Ltd t/a Panubo
4+
#
5+
# This workflow supports release candidate tags. If a tag contains "-rc" for
6+
# example "v1.2.3-rc.1" then the release will be marked as a prerelease.
7+
# Additionally when generating changelog for release notes any RC releases will
8+
# be ignored.
9+
#
10+
# If you want to provide additional release notes you can add a
11+
# _ci_release_notes to a Makefile in the root of the repo. This will be called
12+
# while generating the release notes and will be attended to the end of the auto
13+
# generated release notes. If the command is absent or fails the failure will be
14+
# ignored. Additionally the tag/ref_name will be passed with TAG="${TAG#v}"
15+
# which will strip the "v" prefix from the tag, this is useful for listing
16+
# container images with their tag.
17+
18+
name: GitHub Release
19+
20+
on:
21+
push:
22+
tags:
23+
- "v*"
24+
workflow_call:
25+
26+
permissions:
27+
contents: write
28+
29+
jobs:
30+
build:
31+
name: Create GitHub Release
32+
runs-on: ubuntu-latest
33+
steps:
34+
- name: Checkout code
35+
uses: actions/checkout@v5
36+
with:
37+
fetch-depth: 0 # Required for git log to work
38+
39+
- name: Get Release Notes
40+
env:
41+
TAG: ${{ github.ref_name }}
42+
id: get_release_notes
43+
run: |
44+
tag1="$(git -c 'versionsort.suffix=-' tag --sort=-v:refname | head -1)"
45+
tag2="$(git -c 'versionsort.suffix=-' tag --sort=-v:refname | grep -v '\-rc' | grep -v -w "${tag1}" | head -1)"
46+
{
47+
echo 'notes<<EOF'
48+
echo "Changes since last release:"
49+
echo
50+
git log --graph --pretty=tformat:'%s %H' --abbrev-commit --date=relative "${tag1}"..."${tag2}"
51+
echo
52+
echo "**Full Changelog**: https://github.com/${GITHUB_REPOSITORY}/compare/${tag2}...${tag1}"
53+
# Optionally allow the Makefile to generate some release notes too
54+
make _ci_release_notes TAG=${TAG#v} || true
55+
echo EOF
56+
} >> "${GITHUB_OUTPUT}"
57+
58+
- name: Create Release
59+
id: create_release
60+
env:
61+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62+
TAG: ${{ github.ref_name }}
63+
run: |
64+
gh release create "$TAG" \
65+
--title "Release $TAG" \
66+
--notes "${{ steps.get_release_notes.outputs.notes }}" \
67+
--draft=false \
68+
--prerelease="${{ contains(github.ref, '-rc') }}"

Dockerfile

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
FROM docker.io/alpine:3.23
2+
3+
# Set versions and checksums
4+
ENV \
5+
HELM_VERSION=3.19.5 \
6+
HELM_GPG_KEYS="672C657BE06B4B30969C4A57461449C25E36B98E F1261BDE929012C8FF2E501D6EA5D7598529A53E 967F8AC5E2216F9F4FD270AD92AA783CBAAE8E3B 76939899B137D575D3274E756DCCB9D752D35BA8 49D09C86C3DC8DA3F0A076221EF612347F8A9958 ABA2529598F6626C420D335B62F49E747D911B60 4AB45F1CB0D292975C6371436E2A23D806B6E6DD 208DD36ED5BB3745A16743A4C7C6FBB5B91C1155 7FEC81FACC7FFB2A010ADD13C2D40F4D8196E874" \
7+
KUBECTL_VERSION=1.33.7 \
8+
SOPS_VERSION=3.11.0 \
9+
VALS_VERSION=0.43.1 \
10+
VALS_CHECKSUM_X86_64=50403f8a13d534b7bd1392d3228b5785cad342b4c8819b39c075f132680afece \
11+
VALS_CHECKSUM_AARCH64=16e55cefa2e6ae016e12c39fad6361695221dece97e8046615ac002d692cde22 \
12+
HELM_SECRETS_VERSION=4.7.5 \
13+
HELM_SECRETS_CHECKSUM=f1e332f159e67100612815dcb8773ea46ae75a682fcf058c29bd300581fe2401 \
14+
CURL_VERSION=8.18.0 \
15+
CURL_CHECKSUM_X86_64=35d3377193d67b4e0aa0931da4f443c8fccfa26d889e2f40457220afedfc9d7c \
16+
CURL_CHECKSUM_AARCH64=1e9bf12c523254a54b79d07cdb621aa0830509a82646fe8be13340a03fcbbd05
17+
18+
# Install some system packages
19+
RUN set -x \
20+
&& mkdir -p /gitops-tools/helm-plugins \
21+
&& apk add --no-cache gnupg ca-certificates cosign \
22+
;
23+
24+
# Install Helm and validate the release is signed by a trusted releaser
25+
# Use Helm's KEYS file as the key source but only import the trusted keys from $HELM_GPG_KEYS
26+
RUN set -x \
27+
&& if [ "$(uname -m)" = "x86_64" ] ; then \
28+
ARCH="amd64"; \
29+
elif [ "$(uname -m)" = "aarch64" ]; then \
30+
ARCH="arm64"; \
31+
fi \
32+
&& IMPORT_GPG="$(mktemp -d)" \
33+
&& HELM_GPG="$(mktemp -d)" \
34+
&& wget --no-verbose "https://raw.githubusercontent.com/helm/helm/main/KEYS" -O /tmp/helm-KEYS \
35+
&& gpg --homedir "${IMPORT_GPG}" --import /tmp/helm-KEYS \
36+
&& for key in ${HELM_GPG_KEYS}; do gpg --homedir "${IMPORT_GPG}" --export "${key}" | gpg --homedir "${HELM_GPG}" --import; done \
37+
&& wget --no-verbose "https://get.helm.sh/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz" -O /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz \
38+
&& wget --no-verbose "https://get.helm.sh/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256" -O /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256 \
39+
&& wget --no-verbose "https://github.com/helm/helm/releases/download/v${HELM_VERSION}/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.asc" -O /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.asc \
40+
&& wget --no-verbose "https://github.com/helm/helm/releases/download/v${HELM_VERSION}/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256.asc " -O /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256.asc \
41+
&& echo "$(cat /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256) /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz" | sha256sum -c - \
42+
&& gpg --batch --homedir "${HELM_GPG}" --no-default-keyring --verify /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.asc /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz \
43+
&& gpg --batch --homedir "${HELM_GPG}" --no-default-keyring --verify /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256.asc /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256 \
44+
&& tar -C /gitops-tools -zxf /tmp/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz --strip-components 1 linux-${ARCH}/helm \
45+
&& chmod +x /gitops-tools/helm \
46+
&& rm -rf /tmp/* \
47+
;
48+
49+
# Install kubectl and verify with cosign
50+
RUN set -x \
51+
&& if [ "$(uname -m)" = "x86_64" ] ; then \
52+
ARCH="amd64"; \
53+
elif [ "$(uname -m)" = "aarch64" ]; then \
54+
ARCH="arm64"; \
55+
fi \
56+
&& wget --no-verbose "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl" -O /gitops-tools/kubectl \
57+
&& wget --no-verbose "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl.sha256" -O /tmp/kubectl.sha256 \
58+
&& wget --no-verbose "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl.sig" -O /tmp/kubectl.sig \
59+
&& wget --no-verbose "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl.cert" -O /tmp/kubectl.cert \
60+
&& (cd /gitops-tools; echo "$(cat /tmp/kubectl.sha256) kubectl" | sha256sum -c -) \
61+
&& cosign verify-blob "/gitops-tools/kubectl" \
62+
--signature "/tmp/kubectl.sig" \
63+
--certificate "/tmp/kubectl.cert" \
64+
--certificate-identity krel-staging@k8s-releng-prod.iam.gserviceaccount.com \
65+
--certificate-oidc-issuer https://accounts.google.com \
66+
&& chmod +x /gitops-tools/kubectl \
67+
&& rm -rf /tmp/* \
68+
;
69+
70+
# Install SOPS and verify with cosign
71+
RUN set -x \
72+
&& if [ "$(uname -m)" = "x86_64" ] ; then \
73+
ARCH="amd64"; \
74+
elif [ "$(uname -m)" = "aarch64" ]; then \
75+
ARCH="arm64"; \
76+
fi \
77+
&& wget --no-verbose "https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.linux.${ARCH}" -O /tmp/sops-v${SOPS_VERSION}.linux.${ARCH} \
78+
&& wget --no-verbose "https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.checksums.txt" -O /tmp/sops-v${SOPS_VERSION}.checksums.txt \
79+
&& wget --no-verbose "https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.checksums.pem" -O /tmp/sops-v${SOPS_VERSION}.checksums.pem \
80+
&& wget --no-verbose "https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.checksums.sig" -O /tmp/sops-v${SOPS_VERSION}.checksums.sig \
81+
&& (cd /tmp; grep "sops-v${SOPS_VERSION}.linux.${ARCH}" /tmp/sops-v${SOPS_VERSION}.checksums.txt | sha256sum -c -) \
82+
&& cosign verify-blob "/tmp/sops-v${SOPS_VERSION}.checksums.txt" \
83+
--certificate "/tmp/sops-v${SOPS_VERSION}.checksums.pem" \
84+
--signature "/tmp/sops-v${SOPS_VERSION}.checksums.sig" \
85+
--certificate-identity-regexp="https://github.com/getsops" \
86+
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
87+
&& mv /tmp/sops-v${SOPS_VERSION}.linux.${ARCH} /gitops-tools/sops \
88+
&& chmod +x /gitops-tools/sops \
89+
&& rm -rf /tmp/* \
90+
;
91+
92+
# Install helm vals and verify with checksum
93+
RUN set -x \
94+
&& if [ "$(uname -m)" = "x86_64" ] ; then \
95+
VALS_CHECKSUM="${VALS_CHECKSUM_X86_64}"; \
96+
ARCH="amd64"; \
97+
elif [ "$(uname -m)" = "aarch64" ]; then \
98+
VALS_CHECKSUM="${VALS_CHECKSUM_AARCH64}"; \
99+
ARCH="arm64"; \
100+
fi \
101+
&& wget --no-verbose "https://github.com/helmfile/vals/releases/download/v${VALS_VERSION}/vals_${VALS_VERSION}_linux_${ARCH}.tar.gz" -O /tmp/vals_v${VALS_VERSION}_linux_${ARCH}.tar.gz \
102+
&& (cd /tmp; echo "${VALS_CHECKSUM} vals_v${VALS_VERSION}_linux_${ARCH}.tar.gz" | sha256sum -c -) \
103+
&& tar -C /gitops-tools -zxf /tmp/vals_v${VALS_VERSION}_linux_${ARCH}.tar.gz vals \
104+
&& chmod +x /gitops-tools/vals \
105+
&& rm -rf /tmp/* \
106+
;
107+
108+
# Install helm-secrets plugin
109+
RUN set -x \
110+
&& wget --no-verbose "https://github.com/jkroepke/helm-secrets/releases/download/v${HELM_SECRETS_VERSION}/helm-secrets.tar.gz" -O /tmp/helm-secrets.tar.gz \
111+
&& (cd /tmp; echo "${HELM_SECRETS_CHECKSUM} helm-secrets.tar.gz" | sha256sum -c -) \
112+
&& tar -C /gitops-tools/helm-plugins -zxf /tmp/helm-secrets.tar.gz \
113+
&& rm -rf /tmp/* \
114+
;
115+
116+
# Install static curl
117+
RUN set -x \
118+
&& if [ "$(uname -m)" = "x86_64" ] ; then \
119+
CURL_CHECKSUM="${CURL_CHECKSUM_X86_64}"; \
120+
ARCH="x86_64"; \
121+
elif [ "$(uname -m)" = "aarch64" ]; then \
122+
CURL_CHECKSUM="${CURL_CHECKSUM_AARCH64}"; \
123+
ARCH="aarch64"; \
124+
fi \
125+
&& wget --no-verbose "https://github.com/stunnel/static-curl/releases/download/${CURL_VERSION}/curl-linux-${ARCH}-musl-${CURL_VERSION}.tar.xz" -O /tmp/curl-linux-${ARCH}-musl-${CURL_VERSION}.tar.xz \
126+
&& tar -C /gitops-tools -Jxf /tmp/curl-linux-${ARCH}-musl-${CURL_VERSION}.tar.xz curl \
127+
&& (cd /gitops-tools; echo "${CURL_CHECKSUM} curl" | sha256sum -c -) \
128+
&& chmod +x /gitops-tools/curl \
129+
;
130+
131+
# Add some env vars
132+
ENV \
133+
PATH="/gitops-tools:${PATH}" \
134+
HELM_PLUGINS=/gitops-tools/helm-plugins/ \
135+
HELM_SECRETS_CURL_PATH=/gitops-tools/curl \
136+
HELM_SECRETS_SOPS_PATH=/gitops-tools/sops \
137+
HELM_SECRETS_VALS_PATH=/gitops-tools/vals \
138+
HELM_SECRETS_HELM_PATH=/gitops-tools/helm \
139+
HELM_SECRETS_KUBECTL_PATH=/gitops-tools/kubectl \
140+
HELM_SECRETS_BACKEND=sops \
141+
HELM_SECRETS_VALUES_ALLOW_SYMLINKS="false" \
142+
HELM_SECRETS_VALUES_ALLOW_ABSOLUTE_PATH="true" \
143+
HELM_SECRETS_VALUES_ALLOW_PATH_TRAVERSAL="false" \
144+
HELM_SECRETS_WRAPPER_ENABLED="true" \
145+
HELM_SECRETS_DECRYPT_SECRETS_IN_TMP_DIR="true"

Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
NAME := gitops-toolbox
2+
TAG := test
3+
IMAGE_NAME := panubo/$(NAME)
4+
5+
.PHONY: help build build-quick run-nginx run-nginx-spa run-s3sync shell push clean
6+
7+
help:
8+
@printf "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)\n"
9+
10+
build: ## build image
11+
docker build -t $(IMAGE_NAME):$(TAG) .
12+
13+
run: ## run the container
14+
docker run --rm -it $(IMAGE_NAME):$(TAG)
15+
16+
test: ## run test suite
17+
( cd tests; bats -j 4 . )
18+
19+
_ci_test:
20+
-mkdir tests/results
21+
( cd tests; bats -j 4 --report-formatter junit -o results . )
22+
23+
_ci_release_notes:
24+
@echo "## Installed Tools"
25+
@grep -E '(HELM_VERSION|KUBECTL_VERSION|SOPS_VERSION|VALS_VERSION|HELM_SECRETS_VERSION|CURL_VERSION)=' Dockerfile | \
26+
sed -e 's/^[[:space:]]*//' \
27+
-e 's/ \\//' \
28+
-e 's/HELM_VERSION=/- helm: /' \
29+
-e 's/KUBECTL_VERSION=/- kubectl: /' \
30+
-e 's/SOPS_VERSION=/- sops: /' \
31+
-e 's/VALS_VERSION=/- vals: /' \
32+
-e 's/HELM_SECRETS_VERSION=/- helm-secrets: /' \
33+
-e 's/CURL_VERSION=/- curl: /'
34+
@echo ""
35+
@echo "## Container Images"
36+
@echo "- quay.io/$(IMAGE_NAME):$(TAG)"
37+
@echo "- public.ecr.aws/$(IMAGE_NAME):$(TAG)"

0 commit comments

Comments
 (0)