summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-15 02:55:52 -0500
committerChristian Cleberg <[email protected]>2026-07-15 02:55:52 -0500
commit8d08f343c930f556c6ab016be9d00b23f1e516e3 (patch)
tree59bf9d706f5d28ca3f962403a9263a1be2f6860b
parent47bfe56e728d046fc8fb78b784efe6926f08ff9e (diff)
downloadskunky-art-8d08f343c930f556c6ab016be9d00b23f1e516e3.tar.gz
skunky-art-8d08f343c930f556c6ab016be9d00b23f1e516e3.tar.bz2
skunky-art-8d08f343c930f556c6ab016be9d00b23f1e516e3.zip
ci: publish multi-arch image to GHCR on release tagsv1.3.4
Build and push linux/amd64 + linux/arm64 images to ghcr.io/zerolabsco/skunky-art on every v* tag, with a signed provenance attestation. The Dockerfile cross-compiles from $BUILDPLATFORM, so the arm64 image builds without QEMU emulation. Default both compose examples to the published image and keep `build: .` commented out for building from a checkout, and extend dependabot to the github-actions and docker ecosystems.
-rw-r--r--.github/dependabot.yml10
-rw-r--r--.github/workflows/release.yml71
-rwxr-xr-xREADME.md11
-rwxr-xr-xcompose.example.yaml7
-rw-r--r--compose.vpn_example.yml6
5 files changed, 103 insertions, 2 deletions
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index cd88554..8caee55 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -9,3 +9,13 @@ updates:
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+
+ - package-ecosystem: "docker"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..00a6e60
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,71 @@
+name: Release image
+
+on:
+ push:
+ tags:
+ - "v*"
+ workflow_dispatch:
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ id-token: write
+ attestations: write
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ # The Dockerfile cross-compiles with Go's GOOS/GOARCH from $BUILDPLATFORM,
+ # so no QEMU emulation is needed for the arm64 image.
+ - name: Set up Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to ${{ env.REGISTRY }}
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Derive tags and labels
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ # A semver tag v1.3.4 publishes 1.3.4, 1.3, 1 and latest.
+ # A manual run from a branch publishes only that branch name, so
+ # dispatching from main never moves the latest tag.
+ tags: |
+ type=semver,pattern={{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=ref,event=branch
+ labels: |
+ org.opencontainers.image.title=SkunkyArt
+ org.opencontainers.image.description=An alternative frontend for DeviantArt that works entirely without JavaScript
+
+ - name: Build and push
+ id: build
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ platforms: linux/amd64,linux/arm64
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ - name: Attest build provenance
+ uses: actions/attest-build-provenance@v2
+ with:
+ subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ subject-digest: ${{ steps.build.outputs.digest }}
+ push-to-registry: true
diff --git a/README.md b/README.md
index 396628a..9dd9d17 100755
--- a/README.md
+++ b/README.md
@@ -20,6 +20,17 @@ can also add the `-ldflags "-w -s"` argument (GCCGO has a different name for it
`go build -tags embed -ldflags "-w -s"`
+## Docker
+Prebuilt multi-arch images (`linux/amd64`, `linux/arm64`) are published to GHCR
+on every release tag:
+
+`docker pull ghcr.io/zerolabsco/skunky-art:latest`
+
+Each release is tagged `1.3.3`, `1.3`, `1` and `latest`; pin an exact version if
+you want reproducible upgrades. `compose.example.yaml` uses this image by
+default and keeps a commented-out `build: .` for building from a checkout.
+`compose.vpn_example.yml` does the same, plus an optional VPN egress sidecar.
+
## Setup
The sample config is in the `config.example.json` file. For custom config, use
the `--config` option.
diff --git a/compose.example.yaml b/compose.example.yaml
index 5eead70..2e2f088 100755
--- a/compose.example.yaml
+++ b/compose.example.yaml
@@ -2,7 +2,12 @@ services:
skunkyart:
container_name: skunkyart
restart: unless-stopped
- build: .
+ # Published multi-arch image (linux/amd64, linux/arm64). Pin a release tag
+ # (e.g. :1.3.3) instead of :latest if you want reproducible upgrades.
+ image: ghcr.io/zerolabsco/skunky-art:latest
+ # To build from this checkout instead, comment out `image:` above and
+ # uncomment the line below, then `docker compose up -d --build`.
+ #build: .
ports:
- "127.0.0.1:3003:3003"
security_opt:
diff --git a/compose.vpn_example.yml b/compose.vpn_example.yml
index 701c96d..27cd488 100644
--- a/compose.vpn_example.yml
+++ b/compose.vpn_example.yml
@@ -48,7 +48,11 @@ services:
skunkyart:
container_name: skunkyart
restart: unless-stopped
- build: .
+ # Published multi-arch image; pin a release tag (e.g. :1.3.3) for
+ # reproducible upgrades. To build from this checkout instead, comment out
+ # `image:` and uncomment `build:`, then `docker compose up -d --build`.
+ image: ghcr.io/zerolabsco/skunky-art:latest
+ #build: .
ports:
- "127.0.0.1:3003:3003"
security_opt: