Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 115 additions & 35 deletions .github/workflows/build-and-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,67 @@ on:
permissions:
contents: write
packages: write
security-events: write

jobs:
scan-dependencies:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- uses: actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 # v4.8.0
# this action requires a base and head
# ensure that trunk changes require pull request checks to pass
if: ${{ github.event_name == 'pull_request' }}

scan-codeql:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is common to use a version tag than commit sha with GitHub Actions, but I'm fine with this. We'd need a quick script or some logic to update this though

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I came across this approach while researching these code scanning tools, where I came saw code written by more security-conscious folk. The concern with tags, as usual, is that they can change. You would normally have a lockfile with a hash for dependencies, but in the case of github workflows there is none. This is the next best thing.

I accept that it's a bit janky and appreciate that this requires some flexibility from developers' POV, and I agree that an updater tool would be great.


- uses: github/codeql-action/init@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
with:
languages: actions,go
- uses: github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
with:
output: codeql-sarif
- name: Check success or failure
# github/codeql-action/analyze doesn't fail the pipeline when it finds vulnerabilities
run: |
set -euo pipefail
shopt -s nullglob
files=(codeql-sarif/*.sarif)
if [ ${#files[@]} -eq 0 ]; then
echo "No SARIF files produced by CodeQL analyze."
exit 1
fi
# Count non-note results across all SARIF files
count="$(jq -s 'map(.runs[].results // []) | flatten | map(select(.level != "note")) | length' "${files[@]}")"
echo "Non-note CodeQL results: ${count}"
if [ "${count}" -gt 0 ]; then
echo "::error::CodeQL produced ${count} alerts (warning/error)."
exit 1
fi

build-go:
needs: [ scan-dependencies, scan-codeql ]
runs-on: ubuntu-latest
strategy:
matrix:
arch: ${{ fromJson(inputs.architectures) }}
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Install Go
uses: actions/setup-go@v5
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version-file: go.mod

- name: Run linter
uses: golangci/golangci-lint-action@v8
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0

- name: Run tests
run: |-
Expand All @@ -64,73 +107,110 @@ jobs:
./cmd/multigres-operator

- name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: multigres-operator-${{matrix.arch}}
path: dist/*
if-no-files-found: error
retention-days: 7

build-push-container:
build-scan-push-container:
needs: [ build-go ]
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0

- name: Set up Docker for multi-platform
uses: docker/setup-docker-action@b60f85385d03ac8acfca6d9996982511d8620a19 # v4.3.0
with:
daemon-config: |
{
"features": {
"containerd-snapshotter": true
}
}

- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1

- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
pattern: multigres-operator-*
path: dist/

- name: Log into registry
uses: docker/login-action@v3
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract container metadata
id: meta
uses: docker/metadata-action@v5
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch,prefix=
type=ref,event=tag,prefix=
type=sha,format=short,prefix=
type=sha,format=long,prefix=

- uses: actions/download-artifact@v5
with:
pattern: multigres-operator-*
path: dist/

- name: Build and push container image
id: build-and-push
uses: docker/build-push-action@v5
- name: Build container image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: Containerfile
platforms: linux/${{ join(fromJson(inputs.architectures), ',linux/') }}
push: ${{ inputs.push-container-image }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
load: true
push: false
tags: "ghcr.io/${{ github.repository }}:${{ github.sha }}"
provenance: false
cache-from: type=gha
cache-to: type=gha,mode=max
outputs: type=oci,dest=container-image.tar

- name: Push to registry (sha)
run: |
IMAGE="ghcr.io/${{ github.repository }}"
docker push "$IMAGE:${{ github.sha }}"

# grype requires that the container image be pushed already because
# the scanner runs in a container with a different local registry
- name: Scan image with grype
id: scan
uses: anchore/scan-action@f6601287cdb1efc985d6b765bbf99cb4c0ac29d8 # v7.0.0
continue-on-error: true
with:
cache-db: true
image: "ghcr.io/${{ github.repository }}:${{ github.sha }}"
output-file: grype.sarif
severity-cutoff: critical # TODO: lower this once vulns are fixed
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7
with:
sarif_file: grype.sarif
- name: Check success or failure
if: ${{ steps.scan.outcome == 'failure' }}
run: exit 1

- name: Push to registry (proper)
if: ${{ inputs.push-container-image }}
run: |
IMAGE="ghcr.io/${{ github.repository }}"
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
docker tag "$IMAGE:${{ github.sha }}" "$IMAGE:latest"
docker push "$IMAGE:latest"
fi
if [ "${{ github.ref_type }}" = "tag" ]; then
docker tag "$IMAGE:${{ github.sha }}" "$IMAGE:${{ github.ref_name }}"
docker push "$IMAGE:${{ github.ref_name }}"
fi

create-release:
needs: [ build-go ]
needs: [ build-scan-push-container ]
runs-on: ubuntu-latest
if: ${{ inputs.create-release }}
steps:
- uses: actions/download-artifact@v5
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
pattern: "*"
path: dist/

- name: Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # 2.4.0
with:
files: dist/**
1 change: 1 addition & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
permissions:
contents: write
packages: write
security-events: write

jobs:
run:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
permissions:
contents: write
packages: write
security-events: write

jobs:
run:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tags.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
permissions:
contents: write
packages: write
security-events: write

jobs:
run:
Expand Down
Loading