feat: initial composite action
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
|||||||
|
# notify-image-updater
|
||||||
|
|
||||||
|
Composite action that POSTs a CloudEvents v1.0 payload to the in-cluster
|
||||||
|
`argocd-image-updater` webhook so it reconciles the matching `ImageUpdater`
|
||||||
|
CR immediately instead of waiting for the next 30s poll tick.
|
||||||
|
|
||||||
|
Pair it with `docker/build-push-action` (or any step that publishes an
|
||||||
|
image and exposes a `digest` output).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: aceofba-cluster
|
||||||
|
container:
|
||||||
|
image: ghcr.io/catthehacker/ubuntu:act-22.04
|
||||||
|
env:
|
||||||
|
IMAGE_UPDATER_WEBHOOK_SECRET: ${{ secrets.IMAGE_UPDATER_WEBHOOK_SECRET }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: https://git.aceofba.se/infra/setup-buildx@v1
|
||||||
|
|
||||||
|
- uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: git.aceofba.se
|
||||||
|
username: ${{ gitea.actor }}
|
||||||
|
password: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
|
||||||
|
- id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: git.aceofba.se/${{ gitea.repository }}
|
||||||
|
tags: |
|
||||||
|
type=sha,prefix=,format=short
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- id: build
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- uses: https://git.aceofba.se/infra/notify-image-updater@v1
|
||||||
|
with:
|
||||||
|
image: git.aceofba.se/${{ gitea.repository }}
|
||||||
|
tag: ${{ steps.meta.outputs.version }}
|
||||||
|
digest: ${{ steps.build.outputs.digest }}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Inputs
|
||||||
|
|
||||||
|
| Name | Required | Default | Description |
|
||||||
|
|------|----------|---------|-------------|
|
||||||
|
| `image` | yes | – | Fully-prefixed image repository, e.g. `git.aceofba.se/owner/repo`. Must match `data.repositoryName` matching in argocd-image-updater's registry config. |
|
||||||
|
| `tag` | yes | – | Tag that was just pushed. |
|
||||||
|
| `digest` | yes | – | Image digest. Use `${{ steps.<build-id>.outputs.digest }}` from `docker/build-push-action`. |
|
||||||
|
| `secret` | no | `${{ env.IMAGE_UPDATER_WEBHOOK_SECRET }}` | CloudEvents shared secret. Read by default from the `IMAGE_UPDATER_WEBHOOK_SECRET` env var (set it from a repo or org Gitea Actions secret). |
|
||||||
|
| `webhook-url` | no | `http://argocd-image-updater.argocd.svc.cluster.local:8080/webhook` | Webhook endpoint. Only override for non-default clusters. |
|
||||||
|
|
||||||
|
## Setting up the secret
|
||||||
|
|
||||||
|
Add an org-level Gitea Actions secret named `IMAGE_UPDATER_WEBHOOK_SECRET`
|
||||||
|
with the value from
|
||||||
|
`infra/clusters` → `base/argo-cd-image-updater/manifests/webhook-secret.yaml`
|
||||||
|
(`stringData.CLOUDEVENTS_WEBHOOK_SECRET`). Repos that build images then
|
||||||
|
just expose it via `env:` at the job level.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The controller polls every 30s by default — fine for most cases but slow
|
||||||
|
when iterating. With a webhook hit at the end of the build, the
|
||||||
|
ImageUpdater controller reconciles immediately, finds the new tag, and
|
||||||
|
pushes the manifest bump. Combined with a Gitea→Argo CD repo webhook, the
|
||||||
|
end-to-end CI-to-deploy latency drops from minutes to seconds.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The cluster's argocd-image-updater service is ClusterIP-only; this
|
||||||
|
action only works from in-cluster runners (which is what
|
||||||
|
`aceofba-cluster` is).
|
||||||
|
- A non-2xx response fails the step. Argo CD reconciliation latency
|
||||||
|
itself is not part of this action — once the manifest commit lands,
|
||||||
|
Argo CD picks it up via its own webhook from Gitea.
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
name: notify-image-updater
|
||||||
|
description: |
|
||||||
|
POSTs a CloudEvents v1.0 envelope to the in-cluster argocd-image-updater
|
||||||
|
webhook so the controller reconciles the matching ImageUpdater CR
|
||||||
|
immediately instead of waiting for the next 30s poll. Pair this with the
|
||||||
|
docker/build-push-action step that publishes the image.
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
image:
|
||||||
|
description: 'Fully-prefixed image repository, e.g. git.aceofba.se/<owner>/<repo>.'
|
||||||
|
required: true
|
||||||
|
tag:
|
||||||
|
description: 'Tag that was just pushed.'
|
||||||
|
required: true
|
||||||
|
digest:
|
||||||
|
description: 'Image digest from docker/build-push-action (steps.<id>.outputs.digest).'
|
||||||
|
required: true
|
||||||
|
secret:
|
||||||
|
description: 'CloudEvents shared secret. Defaults to the IMAGE_UPDATER_WEBHOOK_SECRET repo/org secret.'
|
||||||
|
required: false
|
||||||
|
default: ${{ env.IMAGE_UPDATER_WEBHOOK_SECRET }}
|
||||||
|
webhook-url:
|
||||||
|
description: 'Webhook endpoint. Override only when running against a non-default cluster.'
|
||||||
|
required: false
|
||||||
|
default: 'http://argocd-image-updater.argocd.svc.cluster.local:8080/webhook'
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Notify argocd-image-updater
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
WEBHOOK_URL: ${{ inputs.webhook-url }}
|
||||||
|
WEBHOOK_SECRET: ${{ inputs.secret }}
|
||||||
|
IMAGE: ${{ inputs.image }}
|
||||||
|
TAG: ${{ inputs.tag }}
|
||||||
|
DIGEST: ${{ inputs.digest }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [[ -z "${WEBHOOK_SECRET}" ]]; then
|
||||||
|
echo "::error::IMAGE_UPDATER_WEBHOOK_SECRET is empty. Set it as a repo/org secret or pass 'secret:' to this action." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
curl -fsS -X POST \
|
||||||
|
"${WEBHOOK_URL}?type=cloudevents&secret=${WEBHOOK_SECRET}" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d @- <<EOF
|
||||||
|
{
|
||||||
|
"specversion": "1.0",
|
||||||
|
"id": "${GITHUB_RUN_ID:-$(date +%s)}-${GITHUB_RUN_ATTEMPT:-1}",
|
||||||
|
"type": "image.push",
|
||||||
|
"source": "git.aceofba.se",
|
||||||
|
"subject": "${IMAGE}:${TAG}",
|
||||||
|
"datacontenttype": "application/json",
|
||||||
|
"data": {
|
||||||
|
"repositoryName": "${IMAGE}",
|
||||||
|
"imageTag": "${TAG}",
|
||||||
|
"imageDigest": "${DIGEST}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
echo "Notified argocd-image-updater: ${IMAGE}:${TAG} (${DIGEST})"
|
||||||
Reference in New Issue
Block a user