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/ssh-check:${GITHUB_REF_NAME}"
echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV
IMAGE_REPO="ghcr.io/kuberhealthy/ssh-check"
IMAGE_TAG="${IMAGE_REPO}:${GITHUB_REF_NAME}"
PACKAGE_URL="https://github.com/orgs/kuberhealthy/packages/container/package/ssh-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: ./Dockerfile
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*\/)?ssh\-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/ssh-check:${SHORT_SHA}"
echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV
IMAGE_REPO="ghcr.io/kuberhealthy/ssh-check"
IMAGE_TAG="${IMAGE_REPO}:${SHORT_SHA}"
LATEST_IMAGE_TAG="${IMAGE_REPO}:latest"
PACKAGE_URL="https://github.com/orgs/kuberhealthy/packages/container/package/ssh-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: ./Dockerfile
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:
- "Dockerfile"
- "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: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: false
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
FROM golang:1.24 AS builder
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24 AS builder
ARG TARGETOS
ARG TARGETARCH
WORKDIR /build
COPY go.mod go.sum /build/

COPY . /build
WORKDIR /build/cmd/ssh-check
ENV CGO_ENABLED=0
RUN go build -v
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -v

FROM scratch
COPY --from=builder /build/cmd/ssh-check/ssh-check /app/ssh-check
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
default: build push

build:
docker build -t rjacks161/ssh-check:v3.0.0 .
docker build -t ghcr.io/kuberhealthy/ssh-check:v3.0.0 .

push:
docker push rjacks161/ssh-check:v3.0.0
docker push ghcr.io/kuberhealthy/ssh-check:v3.0.0
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Check ssh connectivity to nodes within a cluster
This repository builds the container image used by Kuberhealthy to run the ssh-check check.

## Image
- `docker.io/kuberhealthy/ssh-check`
- `ghcr.io/kuberhealthy/ssh-check`
- Tags: short git SHA for `main` pushes and `vX.Y.Z` for releases.

## Quick start
- Apply the example manifest: `kubectl apply -f ssh-check.yaml`
- Apply the example manifest: `kubectl apply -f healthcheck.yaml`
- Edit the manifest to set any required inputs for your environment.

## Build locally
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/ssh-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.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ssh-check

go 1.24
go 1.24.0

require (
github.com/kuberhealthy/kuberhealthy/v3 v3.0.0-20250904060524-9ccb8db8e238
Expand Down
2 changes: 1 addition & 1 deletion ssh-check.yaml → healthcheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ spec:
podSpec:
containers:
- name: ssh-check
image: rjacks161/ssh-check:v1.1.0
image: ghcr.io/kuberhealthy/ssh-check:sha-<short-sha>
imagePullPolicy: IfNotPresent
env:
- name: SSH_PRIVATE_KEY
Expand Down
Loading