From 0abf377f53b137d9acd65a72e5490249fcad4247 Mon Sep 17 00:00:00 2001 From: Meghdad <61308304+MeghdadFadaee@users.noreply.github.com> Date: Fri, 17 Jul 2026 23:03:40 +0330 Subject: [PATCH] Use shared runner image build action --- .dockerignore | 2 + .gitea/workflows/build-runner-image.yml | 66 ++++--------------- README.md | 37 ++++++----- .../requirements.lock => requirements.lock | 0 runner-image/Dockerfile | 26 -------- 5 files changed, 37 insertions(+), 94 deletions(-) create mode 100644 .dockerignore rename runner-image/requirements.lock => requirements.lock (100%) delete mode 100644 runner-image/Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a0457ed --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +** +!requirements.lock diff --git a/.gitea/workflows/build-runner-image.yml b/.gitea/workflows/build-runner-image.yml index 6747706..692b0ef 100644 --- a/.gitea/workflows/build-runner-image.yml +++ b/.gitea/workflows/build-runner-image.yml @@ -5,7 +5,8 @@ on: branches: - main paths: - - runner-image/** + - requirements.lock + - .dockerignore - .gitea/workflows/build-runner-image.yml workflow_dispatch: @@ -13,7 +14,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: mahgit.ir/meghdadfadaee/daily-blackout-check-base:node-20-bookworm + image: mahgit.ir/meghdadfadaee/build-runner-image-base:node-20-bookworm credentials: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_TOKEN }} @@ -21,54 +22,15 @@ jobs: - name: Check out repository 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 - env: - REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} - REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} - run: | - set -eu - registry="mahgit.ir" - image="$registry/meghdadfadaee/daily-blackout-check-runner" - revision="$(git rev-parse --short=12 HEAD)" - candidate="$image:$revision" - - cleanup() { - 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" + uses: https://mahgit.ir/MeghdadFadaee/build-runner-image-action@v1 + with: + registry: mahgit.ir + image: mahgit.ir/meghdadfadaee/daily-blackout-check-runner + source-url: https://mahgit.ir/MeghdadFadaee/daily-blackout-check + registry-username: ${{ secrets.REGISTRY_USERNAME }} + registry-token: ${{ secrets.REGISTRY_TOKEN }} + verify-commands: | + docker run --rm "$IMAGE_REF" python -c "import dotenv, jdatetime, requests" + docker run --rm "$IMAGE_REF" pytest --version + docker run --rm "$IMAGE_REF" ruff --version diff --git a/README.md b/README.md index c230ca9..f8271c6 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ The Node base image is also mirrored in Gitea, so image builds do not contact Docker Hub: ```text -mahgit.ir/meghdadfadaee/daily-blackout-check-base:node-20-bookworm +mahgit.ir/meghdadfadaee/build-runner-image-base:node-20-bookworm ``` ### 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 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 -`main` under `runner-image/` or its own workflow file; it never runs for pull -requests. +preferably repository-level runner. The build workflow runs only for changes to +the root image lock, `.dockerignore`, or its own workflow on `main`; it never +runs for pull requests. ### Image publishing flow The **Build runner image** workflow: -1. Starts in the Gitea-hosted `daily-blackout-check-base:node-20-bookworm` - image and installs the Docker client. -2. Builds using only `runner-image/` as context, so `.env` and outage state are - never included. -3. Runs import, pytest, and Ruff smoke checks inside the candidate image. -4. Pushes an immutable tag using the first 12 characters of the Git commit. -5. Updates `latest` only after the candidate passes verification. +1. Starts in the shared Gitea-hosted `build-runner-image-base:node-20-bookworm` + image. +2. Calls the shared Gitea action + `MeghdadFadaee/build-runner-image-action@v1` to install the Docker client, + authenticate, build, verify, and publish. +3. Uses the action's shared Dockerfile with the root `requirements.lock`. + `.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 -started manually. Image builds require Debian mirrors, PyPI, Gitea, and access -to the Docker socket. Normal test and hourly runs only need Gitea, `gitea.com`, -SAAPA, and EitaaYar. The mirrored Node image is intentionally static; refresh it -from the upstream `node:20-bookworm` image when adopting Node security updates. +It runs automatically when `requirements.lock`, `.dockerignore`, or its workflow +changes on `main`, and can also be started manually. Image builds require Debian +mirrors, PyPI, Gitea, and access to the Docker socket. Normal test and hourly +runs only need Gitea, `gitea.com`, SAAPA, and EitaaYar. The mirrored Node image +is intentionally static; refresh it from the upstream `node:20-bookworm` image +when adopting Node security updates. Deployment order: diff --git a/runner-image/requirements.lock b/requirements.lock similarity index 100% rename from runner-image/requirements.lock rename to requirements.lock diff --git a/runner-image/Dockerfile b/runner-image/Dockerfile deleted file mode 100644 index fd58421..0000000 --- a/runner-image/Dockerfile +++ /dev/null @@ -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"]