Author SHA1 Message Date
Rogee 05e78dc882 ci: publish amd64 image to GHCR
Docker image / Test (push) Canceled after 0s
Docker image / Build and publish (push) Canceled after 0s
2026-08-21 13:55:26 +08:00
5 changed files with 133 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
name: Docker image
on:
push:
branches:
- main
tags:
- "v*"
pull_request:
branches:
- main
workflow_dispatch:
permissions:
contents: read
concurrency:
group: docker-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref_type != 'tag' }}
env:
IMAGE_NAME: ghcr.io/${{ github.repository }}
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: false
- name: Run tests
run: ./scripts/test.sh
build:
name: Build and publish
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate image metadata
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: ${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=sha-
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
- name: Build and push image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: mode=max
sbom: true
+1
View File
@@ -22,3 +22,4 @@
- Do not commit SSClash or Mihomo binaries to this repository. - Do not commit SSClash or Mihomo binaries to this repository.
- The Dockerfile may link to official release URLs and users build the image for their own deployment. - The Dockerfile may link to official release URLs and users build the image for their own deployment.
- Do not publish a prebuilt image containing SSClash without permission from its copyright holder. - Do not publish a prebuilt image containing SSClash without permission from its copyright holder.
- GitHub Actions may push the amd64 image to private GHCR for this deployment; do not make the package public without that permission.
+13
View File
@@ -47,6 +47,19 @@ Versions are pinned in the Dockerfile:
SSClash is verified against the checksum file from its official release. Mihomo amd64 and arm64 archives are verified against pinned SHA-256 values. To update either component, update the version and checksums together, then run the complete test suite. SSClash is verified against the checksum file from its official release. Mihomo amd64 and arm64 archives are verified against pinned SHA-256 values. To update either component, update the version and checksums together, then run the complete test suite.
## GitHub Container Registry
The GitHub Actions workflow builds `linux/amd64` only. SSClash-Go and Mihomo are downloaded and checksum-verified during the Docker build, so the resulting container never downloads executable files at startup.
The workflow runs tests before building, publishes to `ghcr.io/<github-owner>/mohomo-docker`, attaches SBOM and provenance, and creates these tags:
- `latest` and `main` from the default branch;
- the Git tag and major/minor tags from releases such as `v1.2.3`;
- an immutable `sha-<commit>` tag;
- pull-request tags for build validation only, without pushing.
Keep the GHCR package visibility **private**. The workflow deliberately does not attempt to change package visibility. Making an image containing SSClash-Go available to third parties conflicts with the upstream binary license unless the copyright holder grants permission.
## Tests ## Tests
```sh ```sh
+2
View File
@@ -4,6 +4,8 @@ set -eu
project_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) project_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
cd "$project_root" cd "$project_root"
./tests/workflow-contract.sh
unformatted=$(gofmt -l cmd internal) unformatted=$(gofmt -l cmd internal)
if [ -n "$unformatted" ]; then if [ -n "$unformatted" ]; then
echo "Go files require formatting:" >&2 echo "Go files require formatting:" >&2
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
set -eu
workflow=.github/workflows/docker.yml
test -f "$workflow" || {
echo "missing GHCR workflow: $workflow" >&2
exit 1
}
grep -F 'packages: write' "$workflow" >/dev/null
# Match the GitHub expression literally.
# shellcheck disable=SC2016
grep -F 'ghcr.io/${{ github.repository }}' "$workflow" >/dev/null
grep -F 'platforms: linux/amd64' "$workflow" >/dev/null
grep -F 'needs: test' "$workflow" >/dev/null
# Match the GitHub expression literally.
# shellcheck disable=SC2016
grep -F 'push: ${{ github.event_name != '\''pull_request'\'' }}' "$workflow" >/dev/null
if grep -Ei 'arm64|setup-qemu' "$workflow" >/dev/null; then
echo "workflow must build linux/amd64 only and must not configure QEMU" >&2
exit 1
fi
uses_count=$(grep -Ec '^[[:space:]]+uses:' "$workflow")
pinned_count=$(grep -Ec '^[[:space:]]+uses: [^ ]+@[0-9a-f]{40}([[:space:]]|$)' "$workflow")
if [ "$uses_count" -eq 0 ] || [ "$uses_count" -ne "$pinned_count" ]; then
echo "every GitHub Action must be pinned to a full commit SHA" >&2
exit 1
fi