Skip to content

chore(release): v0.2.10 — svg v1, screencast damage fix, zero-blitz s… #29

chore(release): v0.2.10 — svg v1, screencast damage fix, zero-blitz s…

chore(release): v0.2.10 — svg v1, screencast damage fix, zero-blitz s… #29

Workflow file for this run

name: docker
on:
workflow_dispatch:
push:
tags: ["v*"]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# One native runner per architecture (amd64 + arm64) — cross-compiling the
# Rust + BoringSSL + V8 stack under QEMU takes an hour; native arm64 runners
# are free for public repos. Each job pushes arch-suffixed tags; `merge`
# stitches them into multi-arch manifest lists.
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux/amd64
arch: amd64
- os: ubuntu-24.04-arm
platform: linux/arm64
arch: arm64
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Same tag set as the final manifest, each suffixed with -<arch>.
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
flavor: |
suffix=-${{ matrix.arch }},onlatest=true
- uses: docker/build-push-action@v6
with:
context: .
platforms: ${{ matrix.platform }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=build-${{ matrix.arch }}
cache-to: type=gha,scope=build-${{ matrix.arch }},mode=max
# Merge the arch tags into multi-arch manifest lists under the final tags
# (0.2.x, 0.x, latest). `imagetools create` assembles the list server-side
# from the per-arch tags pushed above.
merge:
runs-on: ubuntu-latest
needs: build
permissions:
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Merge arch tags into multi-arch manifests
env:
FINAL_TAGS: ${{ steps.meta.outputs.tags }}
run: |
for tag in $FINAL_TAGS; do
echo "→ ${tag} (amd64 + arm64)"
docker buildx imagetools create \
--tag "$tag" \
"${tag}-amd64" \
"${tag}-arm64"
done
# The arm64 build compiles natively but nothing has ever *executed* it —
# V8 snapshots and BoringSSL asm can build fine and still not run. Pull the
# merged multi-arch tag on a real arm64 runner and smoke it: health,
# status page, cookie-store write under a non-root user.
verify:
runs-on: ubuntu-24.04-arm
needs: merge
steps:
- name: Smoke merged image on native arm64
run: |
# Image tags strip the leading "v" (metadata-action semver format):
# tag pushes verify the bare version, dispatches verify latest.
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
TAG="${GITHUB_REF_NAME#v}"
else
TAG=latest
fi
echo "TAG=$TAG" | tee -a "$GITHUB_ENV"
mkdir -p /tmp/smoke-data/cookies /tmp/smoke-data/downloads && sudo chown -R 1000:1000 /tmp/smoke-data
# Any unresolved dynamic library shows up here first (exit 127 gives
# no such hint from docker run alone).
docker run --rm --entrypoint sh "ghcr.io/yinnho/aginxbrowser:${TAG}" \
-c 'ldd /usr/local/bin/aginxbrowser | grep "not found" || echo "ldd: all libs resolved"'
docker run -d --name smoke -p 18089:8089 \
-e AGINXBROWSER_COOKIE_STORE_DIR=/data/cookies \
-e AGINXBROWSER_DOWNLOAD_DIR=/data/downloads \
-u 1000:1000 \
-v /tmp/smoke-data/cookies:/data/cookies \
-v /tmp/smoke-data/downloads:/data/downloads \
"ghcr.io/yinnho/aginxbrowser:${TAG}"
# Diagnose first — a dead container must print its dying words before
# the curl loop can eat the exit code.
sleep 5
docker ps -a --filter name=smoke --format '{{.Status}}'
docker logs smoke 2>&1 | tail -15 || true
ok=""
for i in $(seq 1 30); do
if curl -fsS http://127.0.0.1:18089/health > /tmp/health.json 2>/dev/null; then ok=1; break; fi
sleep 2
done
echo "--- health body:"
cat /tmp/health.json 2>/dev/null || docker logs smoke 2>&1 | tail -25
test -n "$ok"
echo "--- status page head:"
curl -fsS http://127.0.0.1:18089/ | head -3
echo "--- cookie store written by uid 1000:"
ls -ln /tmp/smoke-data/cookies/ | tail -3
# Mirror to Docker Hub when DOCKERHUB_USERNAME/TOKEN secrets are set
# (steps skip — not fail — otherwise). Copies the merged multi-arch GHCR
# manifests, so no second build. The secrets context can't be referenced in
# `if:`, so each gated step mirrors the secrets into env and tests that.
dockerhub:
runs-on: ubuntu-latest
needs: merge
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- id: meta
uses: docker/metadata-action@v5
with:
images: docker.io/yinnho/aginxbrowser
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Login Docker Hub
env:
DH_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DH_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
if: ${{ env.DH_USERNAME != '' && env.DH_TOKEN != '' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Copy GHCR tags to Docker Hub
env:
DH_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DH_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
# Multi-line output: interpolating it directly into the script
# text splits mid-line into raw shell syntax (the v0.2.2 release
# run died on `syntax error near unexpected token`). Route through
# env so the split happens at word-splitting, not in the source.
DH_TAGS: ${{ steps.meta.outputs.tags }}
if: ${{ env.DH_USERNAME != '' && env.DH_TOKEN != '' }}
run: |
for tag in $DH_TAGS; do
name="${tag##*:}"
echo "→ docker.io/yinnho/aginxbrowser:$name (from ghcr.io/yinnho/aginxbrowser:$name)"
docker buildx imagetools create \
--tag "docker.io/yinnho/aginxbrowser:$name" \
"ghcr.io/yinnho/aginxbrowser:$name"
done