From f2c1bedb6fb714334e6bcad3855b88f34065129b Mon Sep 17 00:00:00 2001 From: Anushka Mittal <138426011+anushkamittal2001@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:37:05 +0530 Subject: [PATCH] add workflow for publish images (#139) * add workflow for publish images Signed-off-by: Anushka Mittal * chore: add actions Signed-off-by: Anushka Mittal * fix: Makefile Signed-off-by: Anushka Mittal * fix: fix tags and version Signed-off-by: Anushka Mittal --------- Signed-off-by: Anushka Mittal --- .github/actions/publish-image/action.yaml | 88 +++++++++++++++++++++ .github/actions/setup-build-env/action.yaml | 37 +++++++++ .github/actions/setup-caches/action.yaml | 24 ++++++ .github/workflows/publish-images.yaml | 75 ++++++++++++++++++ Makefile | 31 +++++++- 5 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 .github/actions/publish-image/action.yaml create mode 100644 .github/actions/setup-build-env/action.yaml create mode 100644 .github/actions/setup-caches/action.yaml create mode 100644 .github/workflows/publish-images.yaml diff --git a/.github/actions/publish-image/action.yaml b/.github/actions/publish-image/action.yaml new file mode 100644 index 0000000..368531c --- /dev/null +++ b/.github/actions/publish-image/action.yaml @@ -0,0 +1,88 @@ +name: Publish image + +description: Publishes a docker image, SBOM, scans vulns, and signs the image. + +inputs: + makefile-target: + required: true + description: makefile target to invoke for publishing image with ko + registry: + required: true + description: registry to publish image to + registry-username: + required: true + description: registry credentials username + registry-password: + required: true + description: registry credentials password + repository: + required: true + description: repository to publish image to + version: + required: true + description: published image version + sign-image: + required: true + description: sign image + sbom-name: + required: true + description: name of the cyclonedx sbom + sbom-repository: + required: true + description: sbom repository + signature-repository: + required: true + description: signature repository + main-path: + required: true + description: path to main go entry point + +outputs: + digest: + value: ${{ steps.digest.outputs.digest }} + description: published image digest + +runs: + using: composite + steps: + - shell: bash + id: ko-publish + env: + REGISTRY: ${{ inputs.registry }} + REPO: ${{ inputs.repository }} + REGISTRY_PASSWORD: ${{ inputs.registry-password }} + COSIGN_REPOSITORY: ${{ inputs.sbom-repository }} + run: | + set -e + echo "digest=$(VERSION=${{ inputs.version }} make ${{ inputs.makefile-target }})" >> $GITHUB_OUTPUT + - uses: CycloneDX/gh-gomod-generate-sbom@d4aee0cf5133055dbd98899978246c10c18c440f # v1.1.0 + with: + version: v1 + args: app -licenses -json -output ${{ inputs.sbom-name }}-bom.cdx.json -main ${{ inputs.main-path }} + - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + with: + name: ${{ inputs.sbom-name }}-bom-cdx + path: ${{ inputs.sbom-name }}-bom.cdx.json + - shell: bash + if: ${{ inputs.sign-image == 'true' }} + env: + COSIGN_REPOSITORY: ${{ inputs.signature-repository }} + run: | + set -e + cosign sign --yes \ + -a "repo=${{ github.repository }}" \ + -a "workflow=${{ github.workflow }}" \ + -a "ref=${{ github.sha }}" \ + ${{ steps.ko-publish.outputs.digest }} + - shell: bash + env: + COSIGN_REPOSITORY: ${{ inputs.sbom-repository }} + run: | + cosign attach sbom --sbom ./${{ inputs.sbom-name }}-bom.cdx.json --type cyclonedx ${{ steps.ko-publish.outputs.digest }} + - shell: bash + id: digest + run: | + echo "The image generated is: ${{ steps.ko-publish.outputs.digest }}" + DIGEST=$(echo ${{ steps.ko-publish.outputs.digest }} | cut -d '@' -f2) + echo "Digest from image is: $DIGEST" + echo "digest=$DIGEST" >> $GITHUB_OUTPUT diff --git a/.github/actions/setup-build-env/action.yaml b/.github/actions/setup-build-env/action.yaml new file mode 100644 index 0000000..6fe3805 --- /dev/null +++ b/.github/actions/setup-build-env/action.yaml @@ -0,0 +1,37 @@ +name: Setup build env + +description: Clone repo, unshallow, setup go, cache and install tools. + +inputs: + unshallow: + description: git unshallow + default: 'true' + free-disk-space: + description: free disk space + default: 'true' + +runs: + using: composite + steps: + - uses: jlumbroso/free-disk-space@76866dbe54312617f00798d1762df7f43def6e5c # v1.2.0 + if: ${{ inputs.free-disk-space == 'true' }} + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: false + - shell: bash + if: ${{ inputs.unshallow == 'true' }} + run: | + git fetch --prune --unshallow + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + with: + go-version: ~1.21.3 + - shell: bash + run: | + go mod download + - shell: bash + run: | + GOCACHE=~/.cache/kyverno/tools make install-tools diff --git a/.github/actions/setup-caches/action.yaml b/.github/actions/setup-caches/action.yaml new file mode 100644 index 0000000..99be715 --- /dev/null +++ b/.github/actions/setup-caches/action.yaml @@ -0,0 +1,24 @@ +name: Setup caches + +description: Setup caches for go modules, tools and build cache. + +inputs: + build-cache-key: + description: build cache prefix + +runs: + using: composite + steps: + - uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }} + - uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2 + with: + path: ~/.cache/kyverno/tools + key: ${{ runner.os }}-cache-kyverno-tools-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }} + - uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2 + if: ${{ inputs.build-cache-key }} + with: + path: ~/.cache/go-build + key: ${{ runner.os }}-build-cache-${{ inputs.build-cache-key }}-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }} diff --git a/.github/workflows/publish-images.yaml b/.github/workflows/publish-images.yaml new file mode 100644 index 0000000..3f493aa --- /dev/null +++ b/.github/workflows/publish-images.yaml @@ -0,0 +1,75 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Publish images + +permissions: {} + +on: + push: + branches: + - 'main' + - 'release*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + publish-images: + runs-on: ubuntu-latest + permissions: + packages: write + id-token: write + outputs: + reports-server-digest: ${{ steps.publish-reports-server.outputs.digest }} + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Setup caches + uses: ./.github/actions/setup-caches + timeout-minutes: 5 + continue-on-error: true + with: + build-cache-key: publish-images + - name: Setup build env + uses: ./.github/actions/setup-build-env + timeout-minutes: 30 + - name: Run Trivy vulnerability scanner in repo mode + uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca # v0.16.1 + with: + scan-type: 'fs' + ignore-unfixed: true + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + - name: Install Cosign + uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0 + - name: Publish reports server + id: publish-reports-server + uses: ./.github/actions/publish-image + with: + makefile-target: ko-publish-reports-server + registry: ghcr.io + registry-username: ${{ github.actor }} + registry-password: ${{ secrets.GITHUB_TOKEN }} + repository: ${{ github.repository_owner }} + version: ${{ github.ref_name }} + sign-image: true + sbom-name: reports-server + sbom-repository: ghcr.io/${{ github.repository_owner }}/sbom + signature-repository: ghcr.io/${{ github.repository_owner }}/signatures + main-path: . + generate-reports-server-provenance: + needs: publish-images + permissions: + id-token: write # To sign the provenance. + packages: write # To upload assets to release. + actions: read # To read the workflow path. + # NOTE: The container generator workflow is not officially released as GA. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0 + with: + image: ghcr.io/${{ github.repository_owner }}/reports-server + digest: "${{ needs.publish-images.outputs.reports-server-digest }}" + registry-username: ${{ github.actor }} + secrets: + registry-password: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/Makefile b/Makefile index 514136e..d67c285 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ GOOS ?= $(shell go env GOOS) GOARCH ?= $(shell go env GOARCH) REGISTRY ?= ghcr.io REPO ?= reports-server +REPO_REPORTS_SERVER ?= $(REGISTRY)/$(ORG)/$(REPO) ######### # TOOLS # @@ -66,12 +67,22 @@ clean-tools: ## Remove installed tools ######### CGO_ENABLED ?= 0 -LD_FLAGS := "-s -w" LOCAL_PLATFORM := linux/$(GOARCH) KO_REGISTRY := ko.local -KO_TAGS := $(GIT_SHA) KO_CACHE ?= /tmp/ko-cache BIN := reports-server +ifdef VERSION +LD_FLAGS := "-s -w -X $(PACKAGE)/pkg/version.BuildVersion=$(VERSION)" +else +LD_FLAGS := "-s -w" +endif +ifndef VERSION +KO_TAGS := $(GIT_SHA) +else ifeq ($(VERSION),main) +KO_TAGS := $(GIT_SHA),latest +else +KO_TAGS := $(GIT_SHA),$(subst /,-,$(VERSION)) +endif .PHONY: fmt fmt: ## Run go fmt @@ -201,3 +212,19 @@ kind-install: $(HELM) kind-load ## Build image, load it in kind cluster and depl .PHONY: help help: ## Shows the available commands @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-40s\033[0m %s\n", $$1, $$2}' + +################ +# PUBLISH (KO) # +################ + +REGISTRY_USERNAME ?= dummy +PLATFORMS := all + +.PHONY: ko-login +ko-login: $(KO) + @$(KO) login $(REGISTRY) --username $(REGISTRY_USERNAME) --password $(REGISTRY_PASSWORD) + +.PHONY: ko-publish-reports-server +ko-publish-reports-server: ko-login ## Build and publish reports-server image (with ko) + @LD_FLAGS=$(LD_FLAGS) KOCACHE=$(KOCACHE) KO_DOCKER_REPO=$(REPO_REPORTS_SERVER) \ + $(KO) build . --bare --tags=$(KO_TAGS) --platform=$(PLATFORMS) \ No newline at end of file