Use shared runner image build action
All checks were successful
Build runner image / build (push) Successful in 6m48s
Test blackout notifier / test (push) Successful in 3s
Hourly blackout check / check (push) Successful in 4s

This commit is contained in:
Meghdad
2026-07-17 23:03:40 +03:30
parent b8d27a3298
commit 0abf377f53
5 changed files with 37 additions and 94 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
**
!requirements.lock

View File

@@ -5,7 +5,8 @@ on:
branches: branches:
- main - main
paths: paths:
- runner-image/** - requirements.lock
- .dockerignore
- .gitea/workflows/build-runner-image.yml - .gitea/workflows/build-runner-image.yml
workflow_dispatch: workflow_dispatch:
@@ -13,7 +14,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: mahgit.ir/meghdadfadaee/daily-blackout-check-base:node-20-bookworm image: mahgit.ir/meghdadfadaee/build-runner-image-base:node-20-bookworm
credentials: credentials:
username: ${{ secrets.REGISTRY_USERNAME }} username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_TOKEN }} password: ${{ secrets.REGISTRY_TOKEN }}
@@ -21,54 +22,15 @@ jobs:
- name: Check out repository - name: Check out repository
uses: https://gitea.com/actions/checkout@v4 uses: https://gitea.com/actions/checkout@v4
- name: Install Docker client
run: |
set -eu
for attempt in 1 2 3; do
if apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends docker.io; then
break
fi
if [ "$attempt" -eq 3 ]; then
echo "Unable to install the Docker client after 3 attempts"
exit 1
fi
sleep "$((attempt * 5))"
done
rm -rf /var/lib/apt/lists/*
docker version --format 'Docker client {{.Client.Version}}, server {{.Server.Version}}'
- name: Build, verify, and publish image - name: Build, verify, and publish image
env: uses: https://mahgit.ir/MeghdadFadaee/build-runner-image-action@v1
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} with:
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} registry: mahgit.ir
run: | image: mahgit.ir/meghdadfadaee/daily-blackout-check-runner
set -eu source-url: https://mahgit.ir/MeghdadFadaee/daily-blackout-check
registry="mahgit.ir" registry-username: ${{ secrets.REGISTRY_USERNAME }}
image="$registry/meghdadfadaee/daily-blackout-check-runner" registry-token: ${{ secrets.REGISTRY_TOKEN }}
revision="$(git rev-parse --short=12 HEAD)" verify-commands: |
candidate="$image:$revision" docker run --rm "$IMAGE_REF" python -c "import dotenv, jdatetime, requests"
docker run --rm "$IMAGE_REF" pytest --version
cleanup() { docker run --rm "$IMAGE_REF" ruff --version
docker logout "$registry" >/dev/null 2>&1 || true
}
trap cleanup EXIT
printf '%s' "$REGISTRY_TOKEN" | docker login "$registry" \
--username "$REGISTRY_USERNAME" \
--password-stdin
docker build \
--pull \
--label "org.opencontainers.image.revision=$revision" \
--label "org.opencontainers.image.source=https://mahgit.ir/MeghdadFadaee/daily-blackout-check" \
--tag "$candidate" \
runner-image
docker run --rm "$candidate" python -c "import dotenv, jdatetime, requests"
docker run --rm "$candidate" pytest --version
docker run --rm "$candidate" ruff --version
docker push "$candidate"
docker tag "$candidate" "$image:latest"
docker push "$image:latest"

View File

@@ -77,7 +77,7 @@ The Node base image is also mirrored in Gitea, so image builds do not contact
Docker Hub: Docker Hub:
```text ```text
mahgit.ir/meghdadfadaee/daily-blackout-check-base:node-20-bookworm mahgit.ir/meghdadfadaee/build-runner-image-base:node-20-bookworm
``` ```
### Registry credentials ### Registry credentials
@@ -113,27 +113,32 @@ The runner container itself must already mount the same socket, as in the normal
Docker-based `act_runner` setup. Restart the runner after changing its config. Docker-based `act_runner` setup. Restart the runner after changing its config.
Docker socket access is equivalent to control of the Docker host. Use a trusted, Docker socket access is equivalent to control of the Docker host. Use a trusted,
preferably repository-level runner. The build workflow runs only for changes on preferably repository-level runner. The build workflow runs only for changes to
`main` under `runner-image/` or its own workflow file; it never runs for pull the root image lock, `.dockerignore`, or its own workflow on `main`; it never
requests. runs for pull requests.
### Image publishing flow ### Image publishing flow
The **Build runner image** workflow: The **Build runner image** workflow:
1. Starts in the Gitea-hosted `daily-blackout-check-base:node-20-bookworm` 1. Starts in the shared Gitea-hosted `build-runner-image-base:node-20-bookworm`
image and installs the Docker client. image.
2. Builds using only `runner-image/` as context, so `.env` and outage state are 2. Calls the shared Gitea action
never included. `MeghdadFadaee/build-runner-image-action@v1` to install the Docker client,
3. Runs import, pytest, and Ruff smoke checks inside the candidate image. authenticate, build, verify, and publish.
4. Pushes an immutable tag using the first 12 characters of the Git commit. 3. Uses the action's shared Dockerfile with the root `requirements.lock`.
5. Updates `latest` only after the candidate passes verification. `.dockerignore` restricts the build context to that lock, so `.env`, source,
and outage state are never sent to Docker.
4. Runs import, pytest, and Ruff smoke checks inside the candidate image.
5. Pushes an immutable 12-character Git revision tag and updates `latest` only
after the candidate passes verification.
It runs automatically when `runner-image/**` changes on `main` and can also be It runs automatically when `requirements.lock`, `.dockerignore`, or its workflow
started manually. Image builds require Debian mirrors, PyPI, Gitea, and access changes on `main`, and can also be started manually. Image builds require Debian
to the Docker socket. Normal test and hourly runs only need Gitea, `gitea.com`, mirrors, PyPI, Gitea, and access to the Docker socket. Normal test and hourly
SAAPA, and EitaaYar. The mirrored Node image is intentionally static; refresh it runs only need Gitea, `gitea.com`, SAAPA, and EitaaYar. The mirrored Node image
from the upstream `node:20-bookworm` image when adopting Node security updates. is intentionally static; refresh it from the upstream `node:20-bookworm` image
when adopting Node security updates.
Deployment order: Deployment order:

View File

@@ -1,26 +0,0 @@
FROM mahgit.ir/meghdadfadaee/daily-blackout-check-base:node-20-bookworm
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates \
git \
python3 \
python3-pip \
python3-venv \
tzdata && \
rm -rf /var/lib/apt/lists/*
COPY requirements.lock /tmp/requirements.lock
RUN python3 -m venv /opt/blackout-venv && \
/opt/blackout-venv/bin/pip install --no-cache-dir -r /tmp/requirements.lock && \
/opt/blackout-venv/bin/python -c "import dotenv, jdatetime, requests" && \
/opt/blackout-venv/bin/pytest --version && \
/opt/blackout-venv/bin/ruff --version && \
rm /tmp/requirements.lock
ENV PATH="/opt/blackout-venv/bin:$PATH" \
PYTHONDONTWRITEBYTECODE="1" \
PYTHONUNBUFFERED="1"
CMD ["bash"]