Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05e78dc882 |
@@ -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
|
||||
@@ -22,3 +22,4 @@
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
## 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
|
||||
|
||||
```sh
|
||||
|
||||
@@ -4,6 +4,8 @@ set -eu
|
||||
project_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
cd "$project_root"
|
||||
|
||||
./tests/workflow-contract.sh
|
||||
|
||||
unformatted=$(gofmt -l cmd internal)
|
||||
if [ -n "$unformatted" ]; then
|
||||
echo "Go files require formatting:" >&2
|
||||
|
||||
Executable
+30
@@ -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
|
||||
Reference in New Issue
Block a user