Skip to content

build(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1 #292

build(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1

build(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1 #292

Workflow file for this run

name: Build and Push Docker Image
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# PR checks can be superseded. A publishing run must reach its source-head
# checks so an older event can never cancel or overwrite a newer image.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
IMAGE_NAME: aethersailor/rule-bot
permissions:
contents: read
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.14"
cache: pip
- name: Install dependencies
run: pip install -r requirements.txt -r requirements-dev.txt
- name: Run static checks
run: |
python -m compileall -q src tests
ruff check src tests
pip check
- name: Run unit tests
run: python -m unittest discover -s tests -v
- name: Audit Python dependencies
run: pip-audit -r requirements.txt
build-and-push:
needs: validate
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Set up QEMU
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Verify publish source is current master
if: github.event_name != 'pull_request'
shell: bash
env:
EXPECTED_SHA: ${{ github.sha }}
run: |
set -euo pipefail
test "$GITHUB_REF" = "refs/heads/master"
remote_sha="$(git ls-remote origin refs/heads/master | awk '{print $1}')"
test -n "$remote_sha"
if [[ "$remote_sha" != "$EXPECTED_SHA" ]]; then
echo "refusing to publish stale source: expected $EXPECTED_SHA, master is $remote_sha" >&2
exit 1
fi
- name: Extract image metadata
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
with:
images: ${{ env.IMAGE_NAME }}
tags: type=raw,value=sha-${{ github.sha }}
labels: |
org.opencontainers.image.title=Rule Bot
org.opencontainers.image.description=Telegram bot for rule management
org.opencontainers.image.vendor=AetherSailor
org.opencontainers.image.revision=${{ github.sha }}
- name: Build and optionally push immutable multi-arch image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
sbom: true
- name: Smoke test both published architectures
if: github.event_name != 'pull_request'
shell: bash
env:
CANDIDATE_IMAGE: ${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
run: |
set -euo pipefail
for platform in linux/amd64 linux/arm64; do
docker run --rm --pull always --platform "$platform" \
--entrypoint python "$CANDIDATE_IMAGE" \
-c 'import aiohttp, github, maxminddb, telegram; import src.main'
done
- name: Promote current master to latest
if: github.event_name != 'pull_request'
shell: bash
env:
EXPECTED_SHA: ${{ github.sha }}
CANDIDATE_IMAGE: ${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
run: |
set -euo pipefail
remote_sha="$(git ls-remote origin refs/heads/master | awk '{print $1}')"
test -n "$remote_sha"
if [[ "$remote_sha" != "$EXPECTED_SHA" ]]; then
echo "master advanced during build; keeping candidate but not updating latest" >&2
exit 1
fi
docker buildx imagetools create \
--tag "${IMAGE_NAME}:latest" \
"$CANDIDATE_IMAGE"
- name: Verify latest platforms and source revision
if: github.event_name != 'pull_request'
shell: bash
env:
EXPECTED_SHA: ${{ github.sha }}
run: |
set -euo pipefail
image="${IMAGE_NAME}:latest"
for attempt in {1..12}; do
manifest="$(docker buildx imagetools inspect "$image" \
--format '{{json .Manifest}}' 2>/dev/null || true)"
if jq -e '
([.manifests[]?.platform | select(.os == "linux") | .architecture] | index("amd64")) != null
and
([.manifests[]?.platform | select(.os == "linux") | .architecture] | index("arm64")) != null
' <<<"$manifest" >/dev/null 2>&1; then
verified=true
for arch in amd64 arm64; do
digest="$(jq -er --arg arch "$arch" '
.manifests[]
| select(.platform.os == "linux" and .platform.architecture == $arch)
| .digest
' <<<"$manifest")"
image_config="$(docker buildx imagetools inspect \
"${IMAGE_NAME}@${digest}" --format '{{json .Image}}')"
revision="$(jq -r '.config.Labels["org.opencontainers.image.revision"] // empty' \
<<<"$image_config")"
if [[ "$revision" != "$EXPECTED_SHA" ]]; then
verified=false
break
fi
done
if [[ "$verified" == true ]]; then
exit 0
fi
fi
sleep 10
done
echo "latest does not contain verified amd64/arm64 images for $EXPECTED_SHA" >&2
exit 1