Publish v0.1.0 image; fix publish namespace and docker sample workflows
CI Smoke / toolchain (push) Successful in 1s

- publish-image.sh: add REGISTRY_NAMESPACE for Gitea Container Registry path
- sample workflows: run docker login/build/push on host label (bundled docker
  CLI + mounted socket); fix doubled image path in build/push sample
- docs: record v0.1.0 publish and remaining secret-gated push validation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Jason Stedwell
2026-06-29 22:03:58 -05:00
parent ed6a8d847d
commit 12e6135042
5 changed files with 37 additions and 12 deletions
+5
View File
@@ -14,12 +14,17 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- First successful local image build: `custom-gitea-runner:v0.1.0` (act_runner v0.2.11, Node 20, Docker CLI). Runtime smoke test passes 17/17. - First successful local image build: `custom-gitea-runner:v0.1.0` (act_runner v0.2.11, Node 20, Docker CLI). Runtime smoke test passes 17/17.
- First live registration validated against `git.alwisp.com` (Gitea 1.26.4): instance-level runner registers, comes online, runs healthy, and restart reuses the existing config without creating a duplicate. - First live registration validated against `git.alwisp.com` (Gitea 1.26.4): instance-level runner registers, comes online, runs healthy, and restart reuses the existing config without creating a duplicate.
- `.gitea/workflows/ci-smoke.yml`: Phase 3 CI smoke workflow. Runs on the `host` label to validate the bundled toolchain (`actions/checkout@v4`, node/npm/git/docker, mounted Docker socket) directly in the runner container. First run passed. - `.gitea/workflows/ci-smoke.yml`: Phase 3 CI smoke workflow. Runs on the `host` label to validate the bundled toolchain (`actions/checkout@v4`, node/npm/git/docker, mounted Docker socket) directly in the runner container. First run passed.
- Published `registry.alwisp.com/jason/custom-gitea-runner:v0.1.0` (and `:latest`) — first image release to the Gitea Container Registry.
### Changed
- `test/sample-workflows/docker-login.yml` and `docker-build-push.yml`: now run on the `host` label instead of `ubuntu-latest`. Docker build/push need the runner's bundled Docker CLI and mounted socket, which the `ubuntu-latest` node job container does not provide. Also fixed a doubled image path in the build/push sample (`gitea.repository` already includes the owner).
### Fixed ### Fixed
- `docker/runner/Dockerfile`: `COPY` paths for the entrypoint, healthcheck, and smoke-test scripts now resolve from the repo-root build context used by `scripts/build-image.sh` (previously assumed the build context was `docker/runner/`, so the build failed at the `COPY` steps). - `docker/runner/Dockerfile`: `COPY` paths for the entrypoint, healthcheck, and smoke-test scripts now resolve from the repo-root build context used by `scripts/build-image.sh` (previously assumed the build context was `docker/runner/`, so the build failed at the `COPY` steps).
- `scripts/verify-runtime.sh`: now runs the smoke test via `--entrypoint` so it bypasses the `tini`/bootstrap `ENTRYPOINT` instead of triggering the registration flow and failing on a missing `GITEA_INSTANCE_URL`. - `scripts/verify-runtime.sh`: now runs the smoke test via `--entrypoint` so it bypasses the `tini`/bootstrap `ENTRYPOINT` instead of triggering the registration flow and failing on a missing `GITEA_INSTANCE_URL`.
- `docker/runner/docker-entrypoint.sh`: `GITEA_RUNNER_LABELS` is now honored. `act_runner register` ignores its `--labels` flag when a config already exists, so the bootstrap generated a config with default labels and the env var was silently a no-op. The entrypoint now injects the labels into the generated config before registering. - `docker/runner/docker-entrypoint.sh`: `GITEA_RUNNER_LABELS` is now honored. `act_runner register` ignores its `--labels` flag when a config already exists, so the bootstrap generated a config with default labels and the env var was silently a no-op. The entrypoint now injects the labels into the generated config before registering.
- `scripts/deregister-runner.sh`: rewritten to deregister via the Gitea REST API. The previous version called `act_runner daemon --unregister`, a flag/command that does not exist in act_runner — deregistration must go through `DELETE /api/v1/admin/actions/runners/{id}`. Now takes a runner name or id and an admin API token. - `scripts/deregister-runner.sh`: rewritten to deregister via the Gitea REST API. The previous version called `act_runner daemon --unregister`, a flag/command that does not exist in act_runner — deregistration must go through `DELETE /api/v1/admin/actions/runners/{id}`. Now takes a runner name or id and an admin API token.
- `scripts/publish-image.sh`: now supports a `REGISTRY_NAMESPACE` (default `jason`) so images push to `registry.alwisp.com/<owner>/<image>`. The Gitea Container Registry requires an owner namespace; without it the push 404s on blob upload.
--- ---
+2 -1
View File
@@ -161,7 +161,8 @@ The project is considered successful when it can:
### Notes ### Notes
- `.gitea/workflows/ci-smoke.yml` (run 110, `success`) validated on the live runner via the `host` label: `actions/checkout@v4`, bundled node/npm/git/docker versions, and Docker-socket access (`docker info`) all pass. - `.gitea/workflows/ci-smoke.yml` (run 110, `success`) validated on the live runner via the `host` label: `actions/checkout@v4`, bundled node/npm/git/docker versions, and Docker-socket access (`docker info`) all pass.
- `docker/login-action` + `docker build` + `docker push` and publishing the image to `registry.alwisp.com` are blocked on registry credentials (no local docker auth, no repo Action secrets `REGISTRY_USER`/`REGISTRY_TOKEN`). - Image published: `registry.alwisp.com/jason/custom-gitea-runner:v0.1.0` + `:latest` (login via the jason Gitea account succeeded; push validated the registry round-trip).
- `docker/login-action` + `docker build` + `docker push` **from a workflow** still pending: needs repo Action secrets `REGISTRY_USER`/`REGISTRY_TOKEN`. Recommend a dedicated scoped package token rather than the admin API token. Corrected sample workflows (`test/sample-workflows/docker-login.yml`, `docker-build-push.yml`) are ready to run on the `host` label once the secrets exist.
### Exit criteria ### Exit criteria
+12 -2
View File
@@ -4,6 +4,9 @@ set -euo pipefail
IMAGE_NAME="${IMAGE_NAME:-custom-gitea-runner}" IMAGE_NAME="${IMAGE_NAME:-custom-gitea-runner}"
REGISTRY="${REGISTRY:-registry.alwisp.com}" REGISTRY="${REGISTRY:-registry.alwisp.com}"
# Gitea Container Registry namespaces images under an owner (user/org), e.g.
# registry.alwisp.com/<owner>/<image>. Set REGISTRY_NAMESPACE to that owner.
REGISTRY_NAMESPACE="${REGISTRY_NAMESPACE:-jason}"
VERSION="${VERSION:-}" VERSION="${VERSION:-}"
if [ -z "$VERSION" ]; then if [ -z "$VERSION" ]; then
@@ -11,9 +14,16 @@ if [ -z "$VERSION" ]; then
exit 1 exit 1
fi fi
# Build the remote repository path, including the namespace when one is set.
if [ -n "${REGISTRY_NAMESPACE}" ]; then
REMOTE_REPO="${REGISTRY}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}"
else
REMOTE_REPO="${REGISTRY}/${IMAGE_NAME}"
fi
LOCAL_TAG="${IMAGE_NAME}:${VERSION}" LOCAL_TAG="${IMAGE_NAME}:${VERSION}"
REMOTE_TAG="${REGISTRY}/${IMAGE_NAME}:${VERSION}" REMOTE_TAG="${REMOTE_REPO}:${VERSION}"
REMOTE_LATEST="${REGISTRY}/${IMAGE_NAME}:latest" REMOTE_LATEST="${REMOTE_REPO}:latest"
echo "Tagging ${LOCAL_TAG} as ${REMOTE_TAG} ..." echo "Tagging ${LOCAL_TAG} as ${REMOTE_TAG} ..."
docker tag "${LOCAL_TAG}" "${REMOTE_TAG}" docker tag "${LOCAL_TAG}" "${REMOTE_TAG}"
+15 -8
View File
@@ -1,13 +1,19 @@
name: Smoke — Docker Build and Push name: Smoke — Docker Build and Push
# Runs on the `host` label so docker build/push use the runner container's
# bundled Docker CLI and the mounted /var/run/docker.sock. The `ubuntu-latest`
# label runs steps inside a node job container that has neither.
#
# Requires repo Action secrets:
# REGISTRY_USER — registry username (e.g. your Gitea user)
# REGISTRY_TOKEN — a scoped package read/write token (NOT an admin API token)
on: on:
push:
branches: [main]
workflow_dispatch: workflow_dispatch:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: host
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -21,11 +27,12 @@ jobs:
- name: Build and Push - name: Build and Push
run: | run: |
# gitea.repository is already "owner/repo" (e.g. jason/forgerunner)
IMAGE="registry.alwisp.com/${{ gitea.repository }}"
docker build \ docker build \
-t registry.alwisp.com/${{ gitea.repository_owner }}/${{ gitea.repository }}:latest \ -t "${IMAGE}:latest" \
-t registry.alwisp.com/${{ gitea.repository_owner }}/${{ gitea.repository }}:${{ gitea.sha }} \ -t "${IMAGE}:${{ gitea.sha }}" \
-f docker/runner/Dockerfile \ -f docker/runner/Dockerfile \
. .
docker push "${IMAGE}:latest"
docker push registry.alwisp.com/${{ gitea.repository_owner }}/${{ gitea.repository }}:latest docker push "${IMAGE}:${{ gitea.sha }}"
docker push registry.alwisp.com/${{ gitea.repository_owner }}/${{ gitea.repository }}:${{ gitea.sha }}
+3 -1
View File
@@ -5,7 +5,9 @@ on:
jobs: jobs:
login: login:
runs-on: ubuntu-latest # Use `host` so the Docker CLI and mounted socket are available; the
# `ubuntu-latest` job container has neither.
runs-on: host
steps: steps:
- name: Log in to Gitea Container Registry - name: Log in to Gitea Container Registry
uses: docker/login-action@v3 uses: docker/login-action@v3