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
91 changes: 79 additions & 12 deletions .github/workflows/publish-tag.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,108 @@ jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
contents: write
packages: write
steps:
- name: Checkout
- name: Checkout tag
uses: actions/checkout@v4

- name: Validate release tag
run: |
if [[ ! "${GITHUB_REF_NAME}" =~ ^v[0-9]+[.][0-9]+[.][0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
echo "Release tags must use semver like v1.2.3 or v1.2.3-rc.1"
exit 1
fi

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Log in to Docker Hub
- name: Log in to GHCR
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_PAT }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Set image tag
run: |
IMAGE_TAG="kuberhealthy/http-check:${GITHUB_REF_NAME}"
echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV
IMAGE_REPO="ghcr.io/kuberhealthy/http-check"
IMAGE_TAG="${IMAGE_REPO}:${GITHUB_REF_NAME}"
PACKAGE_URL="https://github.com/orgs/kuberhealthy/packages/container/package/http-check"
echo "IMAGE_REPO=${IMAGE_REPO}" >> "$GITHUB_ENV"
echo "IMAGE_TAG=${IMAGE_TAG}" >> "$GITHUB_ENV"
echo "PACKAGE_URL=${PACKAGE_URL}" >> "$GITHUB_ENV"

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ./Containerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.IMAGE_TAG }}

- name: Update healthcheck examples
env:
GH_TOKEN: ${{ github.token }}
run: |
git fetch origin main
git checkout main
git pull --ff-only origin main
ruby -e 'image_tag = ENV.fetch("IMAGE_TAG"); files = Dir.glob("*.yaml") + Dir.glob("*.yml"); files.each do |path| text = File.read(path); updated = text.gsub(/(image:\s+)(?:\S*\/)?http\-check:[^\s]+/) { "#{$1}#{image_tag}" }; File.write(path, updated) if updated != text; end'

if git diff --quiet; then
echo "No healthcheck image references needed updates."
exit 0
fi

git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add '*.yaml' '*.yml'
git commit -m "chore: update healthcheck image for ${GITHUB_REF_NAME}"
git push origin main

- name: Create release notes
run: |
cat > release-images.txt <<EOF
Image: ${IMAGE_TAG}
Platforms: linux/amd64, linux/arm64
GitHub Package: ${PACKAGE_URL}
EOF

cat > release-notes.md <<EOF
Container images were published for this release.

- Image: `${IMAGE_TAG}`
- Platforms: `linux/amd64`, `linux/arm64`
- GitHub Package: ${PACKAGE_URL}

The example healthcheck manifest on `main` was updated to use this image tag.

```sh
docker pull ${IMAGE_TAG}
```
EOF

- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
gh release edit "${GITHUB_REF_NAME}" --title "${GITHUB_REF_NAME}" --notes-file release-notes.md
else
gh release create "${GITHUB_REF_NAME}" --title "${GITHUB_REF_NAME}" --notes-file release-notes.md --verify-tag
fi
gh release upload "${GITHUB_REF_NAME}" release-images.txt --clobber

- name: Publish summary
run: |
TAG="${IMAGE_TAG#*:}"
IMAGE_REPO="${IMAGE_TAG%:*}"
IMAGE_URL="https://hub.docker.com/r/${IMAGE_REPO}/tags?name=${TAG}"
echo "Images pushed:" >> "$GITHUB_STEP_SUMMARY"
echo "Release created:" >> "$GITHUB_STEP_SUMMARY"
echo "- ${GITHUB_REF_NAME}" >> "$GITHUB_STEP_SUMMARY"
echo "Image pushed:" >> "$GITHUB_STEP_SUMMARY"
echo "- ${IMAGE_TAG}" >> "$GITHUB_STEP_SUMMARY"
echo "- ${IMAGE_URL}" >> "$GITHUB_STEP_SUMMARY"
echo "Package:" >> "$GITHUB_STEP_SUMMARY"
echo "- ${PACKAGE_URL}" >> "$GITHUB_STEP_SUMMARY"
30 changes: 20 additions & 10 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,40 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
- name: Log in to GHCR
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_PAT }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Set image tag
run: |
SHORT_SHA=$(git rev-parse --short HEAD)
IMAGE_TAG="kuberhealthy/http-check:${SHORT_SHA}"
echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV
IMAGE_REPO="ghcr.io/kuberhealthy/http-check"
IMAGE_TAG="${IMAGE_REPO}:${SHORT_SHA}"
LATEST_IMAGE_TAG="${IMAGE_REPO}:latest"
PACKAGE_URL="https://github.com/orgs/kuberhealthy/packages/container/package/http-check"
echo "IMAGE_REPO=${IMAGE_REPO}" >> "$GITHUB_ENV"
echo "IMAGE_TAG=${IMAGE_TAG}" >> "$GITHUB_ENV"
echo "LATEST_IMAGE_TAG=${LATEST_IMAGE_TAG}" >> "$GITHUB_ENV"
echo "PACKAGE_URL=${PACKAGE_URL}" >> "$GITHUB_ENV"

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ./Containerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.IMAGE_TAG }}
tags: |
${{ env.IMAGE_TAG }}
${{ env.LATEST_IMAGE_TAG }}

- name: Publish summary
run: |
TAG="${IMAGE_TAG#*:}"
IMAGE_REPO="${IMAGE_TAG%:*}"
IMAGE_URL="https://hub.docker.com/r/${IMAGE_REPO}/tags?name=${TAG}"
echo "Images pushed:" >> "$GITHUB_STEP_SUMMARY"
echo "- ${IMAGE_TAG}" >> "$GITHUB_STEP_SUMMARY"
echo "- ${IMAGE_URL}" >> "$GITHUB_STEP_SUMMARY"
echo "- ${LATEST_IMAGE_TAG}" >> "$GITHUB_STEP_SUMMARY"
echo "Package:" >> "$GITHUB_STEP_SUMMARY"
echo "- ${PACKAGE_URL}" >> "$GITHUB_STEP_SUMMARY"
37 changes: 37 additions & 0 deletions .github/workflows/validate-image-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Validate image build

on:
pull_request:
branches:
- main
paths:
- "Containerfile"
- "go.mod"
- "go.sum"
- "cmd/**"
- ".github/workflows/validate-image-build.yaml"
- ".github/workflows/publish-tag.yaml"
- ".github/workflows/publish.yaml"

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Build image
uses: docker/build-push-action@v6
with:
context: .
file: ./Containerfile
platforms: linux/amd64,linux/arm64
push: false
6 changes: 4 additions & 2 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM golang:1.24 AS builder
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24 AS builder
ARG TARGETOS
ARG TARGETARCH
WORKDIR /build

# Cache module downloads.
Expand All @@ -8,7 +10,7 @@ RUN go mod download
# Copy source and build.
COPY . /build
ENV CGO_ENABLED=0
RUN go build -v -o /build/bin/http-check ./cmd/http-check
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -v -o /build/bin/http-check ./cmd/http-check

# Create a non-root user.
RUN groupadd -g 999 user && \
Expand Down
29 changes: 29 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Release

Releases are automated from semver git tags.

To make a release, create and push a semver tag from the commit you want to release:

```sh
git tag v1.2.3
git push origin v1.2.3
```

The `Publish tag` GitHub Actions workflow runs on `v*` tags and validates the tag format before publishing. Use `vMAJOR.MINOR.PATCH`, such as `v1.2.3`, or a prerelease tag like `v1.2.3-rc.1`.

The workflow publishes this multi-arch image to GitHub Container Registry:

```text
ghcr.io/kuberhealthy/http-check:<tag>
```

The image manifest includes:

- `linux/amd64`
- `linux/arm64`

After the image is pushed, the workflow updates the example healthcheck YAML on `main` to use the released GHCR image tag.

The workflow then creates or updates a GitHub release with the same semver as the tag. The release notes link to the GitHub package, and the release includes a `release-images.txt` asset listing the image and supported platforms.

Docker image tags do not support `+`, so do not use semver build metadata in release tags.
Loading