Commit 8d08f343c9
8d08f343c930f556c6ab016be9d00b23f1e516e3
parent: 47bfe56e72
Verified · cmc
cmc <hello@cleberg.net> · 2026-07-15 07:55 UTC
ci: publish multi-arch image to GHCR on release tags
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.
Layout: unified · split
.github/dependabot.yml
+10
| @@ -9,3 +9,13 @@ updates: |
| 9 | directory: "/" # Location of package manifests |
9 | directory: "/" # Location of package manifests |
| 10 | schedule: |
10 | schedule: |
| 11 | interval: "weekly" |
11 | interval: "weekly" |
| |
12 | |
| |
13 | - package-ecosystem: "github-actions" |
| |
14 | directory: "/" |
| |
15 | schedule: |
| |
16 | interval: "weekly" |
| |
17 | |
| |
18 | - package-ecosystem: "docker" |
| |
19 | directory: "/" |
| |
20 | schedule: |
| |
21 | interval: "weekly" |
.github/workflows/release.yml
added
+71
| @@ -0,0 +1,71 @@ |
| |
1 | name: Release image |
| |
2 | |
| |
3 | on: |
| |
4 | push: |
| |
5 | tags: |
| |
6 | - "v*" |
| |
7 | workflow_dispatch: |
| |
8 | |
| |
9 | env: |
| |
10 | REGISTRY: ghcr.io |
| |
11 | IMAGE_NAME: ${{ github.repository }} |
| |
12 | |
| |
13 | jobs: |
| |
14 | publish: |
| |
15 | runs-on: ubuntu-latest |
| |
16 | permissions: |
| |
17 | contents: read |
| |
18 | packages: write |
| |
19 | id-token: write |
| |
20 | attestations: write |
| |
21 | steps: |
| |
22 | - name: Checkout |
| |
23 | uses: actions/checkout@v4 |
| |
24 | |
| |
25 | # The Dockerfile cross-compiles with Go's GOOS/GOARCH from $BUILDPLATFORM, |
| |
26 | # so no QEMU emulation is needed for the arm64 image. |
| |
27 | - name: Set up Buildx |
| |
28 | uses: docker/setup-buildx-action@v3 |
| |
29 | |
| |
30 | - name: Log in to ${{ env.REGISTRY }} |
| |
31 | uses: docker/login-action@v3 |
| |
32 | with: |
| |
33 | registry: ${{ env.REGISTRY }} |
| |
34 | username: ${{ github.actor }} |
| |
35 | password: ${{ secrets.GITHUB_TOKEN }} |
| |
36 | |
| |
37 | - name: Derive tags and labels |
| |
38 | id: meta |
| |
39 | uses: docker/metadata-action@v5 |
| |
40 | with: |
| |
41 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} |
| |
42 | # A semver tag v1.3.4 publishes 1.3.4, 1.3, 1 and latest. |
| |
43 | # A manual run from a branch publishes only that branch name, so |
| |
44 | # dispatching from main never moves the latest tag. |
| |
45 | tags: | |
| |
46 | type=semver,pattern={{version}} |
| |
47 | type=semver,pattern={{major}}.{{minor}} |
| |
48 | type=semver,pattern={{major}} |
| |
49 | type=ref,event=branch |
| |
50 | labels: | |
| |
51 | org.opencontainers.image.title=SkunkyArt |
| |
52 | org.opencontainers.image.description=An alternative frontend for DeviantArt that works entirely without JavaScript |
| |
53 | |
| |
54 | - name: Build and push |
| |
55 | id: build |
| |
56 | uses: docker/build-push-action@v6 |
| |
57 | with: |
| |
58 | context: . |
| |
59 | platforms: linux/amd64,linux/arm64 |
| |
60 | push: true |
| |
61 | tags: ${{ steps.meta.outputs.tags }} |
| |
62 | labels: ${{ steps.meta.outputs.labels }} |
| |
63 | cache-from: type=gha |
| |
64 | cache-to: type=gha,mode=max |
| |
65 | |
| |
66 | - name: Attest build provenance |
| |
67 | uses: actions/attest-build-provenance@v2 |
| |
68 | with: |
| |
69 | subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} |
| |
70 | subject-digest: ${{ steps.build.outputs.digest }} |
| |
71 | push-to-registry: true |
README.md
+11
| @@ -20,6 +20,17 @@ can also add the `-ldflags "-w -s"` argument (GCCGO has a different name for it |
| 20 | |
20 | |
| 21 | `go build -tags embed -ldflags "-w -s"` |
21 | `go build -tags embed -ldflags "-w -s"` |
| 22 | |
22 | |
| |
23 | ## Docker |
| |
24 | Prebuilt multi-arch images (`linux/amd64`, `linux/arm64`) are published to GHCR |
| |
25 | on every release tag: |
| |
26 | |
| |
27 | `docker pull ghcr.io/zerolabsco/skunky-art:latest` |
| |
28 | |
| |
29 | Each release is tagged `1.3.3`, `1.3`, `1` and `latest`; pin an exact version if |
| |
30 | you want reproducible upgrades. `compose.example.yaml` uses this image by |
| |
31 | default and keeps a commented-out `build: .` for building from a checkout. |
| |
32 | `compose.vpn_example.yml` does the same, plus an optional VPN egress sidecar. |
| |
33 | |
| 23 | ## Setup |
34 | ## Setup |
| 24 | The sample config is in the `config.example.json` file. For custom config, use |
35 | The sample config is in the `config.example.json` file. For custom config, use |
| 25 | the `--config` option. |
36 | the `--config` option. |
compose.example.yaml
+6 −1
| @@ -2,7 +2,12 @@ services: |
| 2 | skunkyart: |
2 | skunkyart: |
| 3 | container_name: skunkyart |
3 | container_name: skunkyart |
| 4 | restart: unless-stopped |
4 | restart: unless-stopped |
| 5 | build: . |
5 | # Published multi-arch image (linux/amd64, linux/arm64). Pin a release tag |
| |
6 | # (e.g. :1.3.3) instead of :latest if you want reproducible upgrades. |
| |
7 | image: ghcr.io/zerolabsco/skunky-art:latest |
| |
8 | # To build from this checkout instead, comment out `image:` above and |
| |
9 | # uncomment the line below, then `docker compose up -d --build`. |
| |
10 | #build: . |
| 6 | ports: |
11 | ports: |
| 7 | - "127.0.0.1:3003:3003" |
12 | - "127.0.0.1:3003:3003" |
| 8 | security_opt: |
13 | security_opt: |
compose.vpn_example.yml
+5 −1
| @@ -48,7 +48,11 @@ services: |
| 48 | skunkyart: |
48 | skunkyart: |
| 49 | container_name: skunkyart |
49 | container_name: skunkyart |
| 50 | restart: unless-stopped |
50 | restart: unless-stopped |
| 51 | build: . |
51 | # Published multi-arch image; pin a release tag (e.g. :1.3.3) for |
| |
52 | # reproducible upgrades. To build from this checkout instead, comment out |
| |
53 | # `image:` and uncomment `build:`, then `docker compose up -d --build`. |
| |
54 | image: ghcr.io/zerolabsco/skunky-art:latest |
| |
55 | #build: . |
| 52 | ports: |
56 | ports: |
| 53 | - "127.0.0.1:3003:3003" |
57 | - "127.0.0.1:3003:3003" |
| 54 | security_opt: |
58 | security_opt: |