|
|
|
@ -23,15 +23,22 @@ on: |
|
|
|
- all |
|
|
|
- standard |
|
|
|
- large_disk |
|
|
|
publish: |
|
|
|
description: 'Publish images and manifests' |
|
|
|
required: true |
|
|
|
type: boolean |
|
|
|
default: false |
|
|
|
|
|
|
|
permissions: |
|
|
|
contents: read |
|
|
|
security-events: write |
|
|
|
|
|
|
|
jobs: |
|
|
|
setup: |
|
|
|
runs-on: ubuntu-latest |
|
|
|
outputs: |
|
|
|
variants: ${{ steps.set-variants.outputs.variants }} |
|
|
|
publish: ${{ steps.set-publish.outputs.publish }} |
|
|
|
steps: |
|
|
|
- name: Select variants for this run |
|
|
|
id: set-variants |
|
|
|
@ -42,6 +49,14 @@ jobs: |
|
|
|
variants='["standard","large_disk"]' |
|
|
|
fi |
|
|
|
echo "variants=$variants" >> "$GITHUB_OUTPUT" |
|
|
|
- name: Select publish mode |
|
|
|
id: set-publish |
|
|
|
run: | |
|
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then |
|
|
|
echo "publish=${{ github.event.inputs.publish }}" >> "$GITHUB_OUTPUT" |
|
|
|
else |
|
|
|
echo "publish=true" >> "$GITHUB_OUTPUT" |
|
|
|
fi |
|
|
|
|
|
|
|
build: |
|
|
|
needs: [setup] |
|
|
|
@ -111,13 +126,13 @@ jobs: |
|
|
|
buildkitd-flags: "--debug" |
|
|
|
buildkitd-config: /tmp/buildkitd.toml |
|
|
|
- name: Login to Docker Hub |
|
|
|
if: github.event_name != 'pull_request' |
|
|
|
if: needs.setup.outputs.publish == 'true' |
|
|
|
uses: docker/login-action@v4 |
|
|
|
with: |
|
|
|
username: ${{ secrets.DOCKER_USERNAME }} |
|
|
|
password: ${{ secrets.DOCKER_PASSWORD }} |
|
|
|
- name: Login to GHCR |
|
|
|
if: github.event_name != 'pull_request' |
|
|
|
if: needs.setup.outputs.publish == 'true' |
|
|
|
uses: docker/login-action@v4 |
|
|
|
with: |
|
|
|
registry: ghcr.io |
|
|
|
@ -129,7 +144,7 @@ jobs: |
|
|
|
DOCKER_BUILDKIT: 1 |
|
|
|
with: |
|
|
|
context: ./docker |
|
|
|
push: ${{ github.event_name != 'pull_request' }} |
|
|
|
push: ${{ needs.setup.outputs.publish == 'true' }} |
|
|
|
file: ./docker/Dockerfile.go_build |
|
|
|
platforms: linux/${{ matrix.platform }} |
|
|
|
# Push to GHCR only during build to avoid Docker Hub rate limits |
|
|
|
@ -149,10 +164,128 @@ jobs: |
|
|
|
# Remove Go build cache |
|
|
|
sudo rm -rf /tmp/go-build* |
|
|
|
|
|
|
|
create-manifest: |
|
|
|
trivy-scan: |
|
|
|
runs-on: ubuntu-latest |
|
|
|
needs: [setup, build] |
|
|
|
if: github.event_name != 'pull_request' |
|
|
|
strategy: |
|
|
|
matrix: |
|
|
|
variant: ${{ fromJSON(needs.setup.outputs.variants) }} |
|
|
|
steps: |
|
|
|
- name: Configure variant |
|
|
|
id: config |
|
|
|
run: | |
|
|
|
if [ "${{ matrix.variant }}" == "large_disk" ]; then |
|
|
|
echo "tag_suffix=_large_disk" >> $GITHUB_OUTPUT |
|
|
|
else |
|
|
|
echo "tag_suffix=" >> $GITHUB_OUTPUT |
|
|
|
fi |
|
|
|
- name: Login to GHCR |
|
|
|
if: needs.setup.outputs.publish == 'true' |
|
|
|
uses: docker/login-action@v4 |
|
|
|
with: |
|
|
|
registry: ghcr.io |
|
|
|
username: ${{ secrets.GHCR_USERNAME }} |
|
|
|
password: ${{ secrets.GHCR_TOKEN }} |
|
|
|
- name: Checkout for local scan build |
|
|
|
if: needs.setup.outputs.publish != 'true' |
|
|
|
uses: actions/checkout@v6 |
|
|
|
with: |
|
|
|
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.source_ref || github.ref }} |
|
|
|
- name: Create BuildKit config for local scan build |
|
|
|
if: needs.setup.outputs.publish != 'true' |
|
|
|
run: | |
|
|
|
cat > /tmp/buildkitd.toml <<EOF |
|
|
|
[registry."docker.io"] |
|
|
|
mirrors = ["https://mirror.gcr.io"] |
|
|
|
EOF |
|
|
|
- name: Set up Docker Buildx for local scan build |
|
|
|
if: needs.setup.outputs.publish != 'true' |
|
|
|
uses: docker/setup-buildx-action@v4 |
|
|
|
with: |
|
|
|
buildkitd-flags: "--debug" |
|
|
|
buildkitd-config: /tmp/buildkitd.toml |
|
|
|
- name: Build local scan image tarball |
|
|
|
if: needs.setup.outputs.publish != 'true' |
|
|
|
uses: docker/build-push-action@v7 |
|
|
|
env: |
|
|
|
DOCKER_BUILDKIT: 1 |
|
|
|
with: |
|
|
|
context: ./docker |
|
|
|
file: ./docker/Dockerfile.go_build |
|
|
|
platforms: linux/amd64 |
|
|
|
outputs: type=docker,dest=/tmp/seaweedfs${{ steps.config.outputs.tag_suffix }}-amd64.tar |
|
|
|
build-args: | |
|
|
|
BUILDKIT_INLINE_CACHE=1 |
|
|
|
BRANCH=${{ github.event_name == 'workflow_dispatch' && github.event.inputs.source_ref || github.sha }} |
|
|
|
${{ matrix.variant == 'large_disk' && 'TAGS=5BytesOffset' || '' }} |
|
|
|
- name: Trivy report (published image) |
|
|
|
if: needs.setup.outputs.publish == 'true' |
|
|
|
# Pin to SHA - mutable tags were compromised (GHSA-69fq-xp46-6x23) |
|
|
|
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 |
|
|
|
with: |
|
|
|
scan-type: image |
|
|
|
# Scan amd64 only - OS packages are identical across architectures |
|
|
|
# since they all use the same alpine base, so a single-arch scan |
|
|
|
# provides sufficient coverage without multiplying CI time. |
|
|
|
image-ref: ghcr.io/chrislusf/seaweedfs:${{ github.event_name == 'workflow_dispatch' && github.event.inputs.image_tag || 'latest' }}${{ steps.config.outputs.tag_suffix }}-amd64 |
|
|
|
scanners: vuln |
|
|
|
vuln-type: os,library |
|
|
|
severity: HIGH,CRITICAL |
|
|
|
ignore-unfixed: true |
|
|
|
limit-severities-for-sarif: true |
|
|
|
format: sarif |
|
|
|
output: trivy-results.sarif |
|
|
|
exit-code: '0' |
|
|
|
- name: Trivy report (local tarball) |
|
|
|
if: needs.setup.outputs.publish != 'true' |
|
|
|
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 |
|
|
|
with: |
|
|
|
input: /tmp/seaweedfs${{ steps.config.outputs.tag_suffix }}-amd64.tar |
|
|
|
scanners: vuln |
|
|
|
vuln-type: os,library |
|
|
|
severity: HIGH,CRITICAL |
|
|
|
ignore-unfixed: true |
|
|
|
limit-severities-for-sarif: true |
|
|
|
format: sarif |
|
|
|
output: trivy-results.sarif |
|
|
|
exit-code: '0' |
|
|
|
- name: Upload Trivy scan results to GitHub Security |
|
|
|
uses: github/codeql-action/upload-sarif@v4 |
|
|
|
if: always() |
|
|
|
with: |
|
|
|
sarif_file: trivy-results.sarif |
|
|
|
- name: Trivy gate (published image) |
|
|
|
if: needs.setup.outputs.publish == 'true' |
|
|
|
# Gate only on fixable high/critical vulnerabilities. Non-fixable |
|
|
|
# findings are still visible in the SARIF upload above. |
|
|
|
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 |
|
|
|
with: |
|
|
|
scan-type: image |
|
|
|
image-ref: ghcr.io/chrislusf/seaweedfs:${{ github.event_name == 'workflow_dispatch' && github.event.inputs.image_tag || 'latest' }}${{ steps.config.outputs.tag_suffix }}-amd64 |
|
|
|
scanners: vuln |
|
|
|
vuln-type: os,library |
|
|
|
severity: HIGH,CRITICAL |
|
|
|
ignore-unfixed: true |
|
|
|
format: table |
|
|
|
exit-code: '1' |
|
|
|
skip-setup-trivy: true |
|
|
|
- name: Trivy gate (local tarball) |
|
|
|
if: needs.setup.outputs.publish != 'true' |
|
|
|
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 |
|
|
|
with: |
|
|
|
input: /tmp/seaweedfs${{ steps.config.outputs.tag_suffix }}-amd64.tar |
|
|
|
scanners: vuln |
|
|
|
vuln-type: os,library |
|
|
|
severity: HIGH,CRITICAL |
|
|
|
ignore-unfixed: true |
|
|
|
format: table |
|
|
|
exit-code: '1' |
|
|
|
skip-setup-trivy: true |
|
|
|
|
|
|
|
create-manifest: |
|
|
|
runs-on: ubuntu-latest |
|
|
|
needs: [setup, build, trivy-scan] |
|
|
|
if: needs.setup.outputs.publish == 'true' && github.event_name != 'pull_request' |
|
|
|
strategy: |
|
|
|
matrix: |
|
|
|
variant: ${{ fromJSON(needs.setup.outputs.variants) }} |
|
|
|
|