reintroduce Trivy reporting and dry-run mode (#8834)
* ci: reintroduce Trivy report and gate workflow * ci: add dry-run mode to container release workflow
This commit is contained in:
143
.github/workflows/container_latest.yml
vendored
143
.github/workflows/container_latest.yml
vendored
@@ -23,15 +23,22 @@ on:
|
|||||||
- all
|
- all
|
||||||
- standard
|
- standard
|
||||||
- large_disk
|
- large_disk
|
||||||
|
publish:
|
||||||
|
description: 'Publish images and manifests'
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
setup:
|
setup:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
variants: ${{ steps.set-variants.outputs.variants }}
|
variants: ${{ steps.set-variants.outputs.variants }}
|
||||||
|
publish: ${{ steps.set-publish.outputs.publish }}
|
||||||
steps:
|
steps:
|
||||||
- name: Select variants for this run
|
- name: Select variants for this run
|
||||||
id: set-variants
|
id: set-variants
|
||||||
@@ -42,6 +49,14 @@ jobs:
|
|||||||
variants='["standard","large_disk"]'
|
variants='["standard","large_disk"]'
|
||||||
fi
|
fi
|
||||||
echo "variants=$variants" >> "$GITHUB_OUTPUT"
|
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:
|
build:
|
||||||
needs: [setup]
|
needs: [setup]
|
||||||
@@ -111,13 +126,13 @@ jobs:
|
|||||||
buildkitd-flags: "--debug"
|
buildkitd-flags: "--debug"
|
||||||
buildkitd-config: /tmp/buildkitd.toml
|
buildkitd-config: /tmp/buildkitd.toml
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
if: github.event_name != 'pull_request'
|
if: needs.setup.outputs.publish == 'true'
|
||||||
uses: docker/login-action@v4
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
if: github.event_name != 'pull_request'
|
if: needs.setup.outputs.publish == 'true'
|
||||||
uses: docker/login-action@v4
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
@@ -129,7 +144,7 @@ jobs:
|
|||||||
DOCKER_BUILDKIT: 1
|
DOCKER_BUILDKIT: 1
|
||||||
with:
|
with:
|
||||||
context: ./docker
|
context: ./docker
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ needs.setup.outputs.publish == 'true' }}
|
||||||
file: ./docker/Dockerfile.go_build
|
file: ./docker/Dockerfile.go_build
|
||||||
platforms: linux/${{ matrix.platform }}
|
platforms: linux/${{ matrix.platform }}
|
||||||
# Push to GHCR only during build to avoid Docker Hub rate limits
|
# Push to GHCR only during build to avoid Docker Hub rate limits
|
||||||
@@ -149,10 +164,128 @@ jobs:
|
|||||||
# Remove Go build cache
|
# Remove Go build cache
|
||||||
sudo rm -rf /tmp/go-build*
|
sudo rm -rf /tmp/go-build*
|
||||||
|
|
||||||
create-manifest:
|
trivy-scan:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [setup, build]
|
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:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
variant: ${{ fromJSON(needs.setup.outputs.variants) }}
|
variant: ${{ fromJSON(needs.setup.outputs.variants) }}
|
||||||
|
|||||||
Reference in New Issue
Block a user