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.
|
- 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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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