Skip to content

Commit

Permalink
feat: sign goreleaser release using cosign custom key-pair (#544)
Browse files Browse the repository at this point in the history
* feat: sign goreleaser release using keyless cosign

* revert go.mod

* bump goreleaser version in ci

* add cosign public key

* use custom key pair to sign and verify releases

---------

Co-authored-by: michaeljguarino <[email protected]>
  • Loading branch information
floreks and michaeljguarino authored Sep 20, 2024
1 parent 209c1e7 commit 972b460
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ jobs:
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: "~> v1"
version: '~> v2'
args: release --clean --split --timeout 90m
env:
CGO_LDFLAGS: "${{ matrix.goos == 'darwin' && '-framework UniformTypeIdentifiers' || '' }}"
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/goreleaser-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: "~> v1"
version: '~> v2'
args: release --clean --split --timeout 90m
env:
CGO_LDFLAGS: "${{ matrix.goos == 'darwin' && '-framework UniformTypeIdentifiers' || '' }}"
Expand All @@ -73,6 +73,9 @@ jobs:
needs: prepare
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
permissions:
contents: write # needed to write releases
id-token: write # needed for keyless signing
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down Expand Up @@ -106,16 +109,20 @@ jobs:
uses: WyriHaximus/github-action-get-previous-tag@v1
env:
INPUT_PREFIX: v
- name: Install Cosign
uses: sigstore/[email protected]
- name: GoReleaser (Release)
uses: goreleaser/goreleaser-action@v6
if: steps.cache.outputs.cache-hit != 'true' # do not run if cache hit
with:
distribution: goreleaser-pro
version: "~> v1"
version: '~> v2'
args: continue --merge --timeout 90m
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
GITLAB_CLIENT_SECRET: ${{ secrets.GITLAB_CLIENT_SECRET }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
GORELEASER_CURRENT_TAG: ${{ github.ref_name }}
Expand Down
25 changes: 19 additions & 6 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
partial:
by: goos

version: 2

before:
hooks:
- go mod tidy
Expand Down Expand Up @@ -35,12 +37,12 @@ builds:
overrides:
- goos: linux
goarch: arm64
tags: [ linux ]
tags: [linux]
env:
- CGO_ENABLED=0
- goos: windows
goarch: arm64
tags: [ windows ]
tags: [windows]
env:
- CGO_ENABLED=0
# Build CLI binary without embedded UI for linux.
Expand All @@ -62,7 +64,7 @@ builds:

archives:
- id: plural-cli
builds: [ plural-cli ]
builds: [plural-cli]
name_template: >-
{{ .ProjectName }}_{{ .Version }}_
{{- title .Os }}_
Expand All @@ -79,7 +81,7 @@ archives:
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
version_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
use: github-native
Expand All @@ -88,6 +90,17 @@ changelog:
- '^docs:'
- '^test:'

signs:
- cmd: cosign
artifacts: checksum
stdin: "{{ .Env.COSIGN_PASSWORD }}"
args:
- sign-blob
- "--key=env://COSIGN_PRIVATE_KEY"
- "--output-signature=${signature}"
- "${artifact}"
- "--yes"

release:
name_template: "{{.ProjectName}}-v{{.Version}}"
header: |
Expand All @@ -106,7 +119,7 @@ git:

brews:
- name: plural
ids: [ plural-cli ]
ids: [plural-cli]
repository:
owner: pluralsh
name: homebrew-plural
Expand Down Expand Up @@ -140,7 +153,7 @@ brews:

# Folder inside the repository to put the formula.
# Default is the root folder.
folder: Formula
directory: Formula

# Your app's homepage.
# Default is empty.
Expand Down
42 changes: 36 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ release:
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -ldflags='$(LDFLAGS)' -o $(OUTFILE) ./cmd/plural
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -ldflags='$(LDFLAGS)' -o $(OUTCTLFILE) ./cmd/pluralctl

.PHONY: goreleaser
goreleaser:
goreleaser release --clean --prepare --single-target --snapshot --verbose

.PHONY: setup
setup: ## sets up your local env (for mac only)
brew install golangci-lint
Expand Down Expand Up @@ -140,20 +144,20 @@ bake-ami:
@echo "baked ami for all regions"

.PHONY: up
up: # spin up local server
up: ## spin up local server
docker-compose up

.PHONY: pull
pull: # pulls new server image
pull: ## pulls new server image
docker-compose pull

.PHONY: serve
serve: build-cloud # build cloud version of plural-cli and start plural serve in docker
serve: build-cloud ## build cloud version of plural-cli and start plural serve in docker
docker kill plural-cli || true
docker run --rm --name plural-cli -p 8080:8080 -d plural-cli:latest-cloud

.PHONY: release-vsn
release-vsn: # tags and pushes a new release
release-vsn: ## tags and pushes a new release
@read -p "Version: " tag; \
git checkout main; \
git pull --rebase; \
Expand All @@ -169,11 +173,11 @@ test: setup-tests
gotestsum --format testname -- -v -race ./pkg/... ./cmd/command/...

.PHONY: format
format: # formats all go code to prep for linting
format: ## formats all go code to prep for linting
docker run --rm -v $(PWD):/app -w /app golangci/golangci-lint:v1.59.1 golangci-lint run --fix

.PHONY: genmock
genmock: # generates mocks before running tests
genmock: ## generates mocks before running tests
hack/gen-client-mocks.sh

.PHONY: lint
Expand All @@ -185,3 +189,29 @@ delete-tag:
@read -p "Version: " tag; \
git tag -d $$tag; \
git push origin :$$tag

REPO_URL := https://github.com/pluralsh/plural-cli/releases/download
OIDC_ISSUER_URL := https://token.actions.githubusercontent.com
VERIFY_FILE_NAME := checksums.txt
RELEASE_ARCHIVE_NAME := plural-cli
VERIFY_TMP_DIR := dist
PUBLIC_KEY_FILE := cosign.pub

.PHONY: verify
verify: ## verifies provided tagged release with cosign
@read -p "Enter version to verify: " tag ;\
echo "Downloading ${VERIFY_FILE_NAME} for tag v$${tag}..." ;\
wget -P ${VERIFY_TMP_DIR} "${REPO_URL}/v$${tag}/checksums.txt" >/dev/null 2>&1 ;\
echo "Verifying signature..." ;\
cosign verify-blob \
--key "${PUBLIC_KEY_FILE}" \
--signature "${REPO_URL}/v$${tag}/${VERIFY_FILE_NAME}.sig" \
"./${VERIFY_TMP_DIR}/${VERIFY_FILE_NAME}" ;\
echo "Verifying archives..." ;\
wget -P ${VERIFY_TMP_DIR} "${REPO_URL}/v$${tag}/${RELEASE_ARCHIVE_NAME}_$${tag}_Darwin_amd64.tar.gz" >/dev/null 2>&1 ;\
wget -P ${VERIFY_TMP_DIR} "${REPO_URL}/v$${tag}/${RELEASE_ARCHIVE_NAME}_$${tag}_Darwin_arm64.tar.gz" >/dev/null 2>&1 ;\
wget -P ${VERIFY_TMP_DIR} "${REPO_URL}/v$${tag}/${RELEASE_ARCHIVE_NAME}_$${tag}_Linux_amd64.tar.gz" >/dev/null 2>&1 ;\
wget -P ${VERIFY_TMP_DIR} "${REPO_URL}/v$${tag}/${RELEASE_ARCHIVE_NAME}_$${tag}_Linux_arm64.tar.gz" >/dev/null 2>&1 ;\
wget -P ${VERIFY_TMP_DIR} "${REPO_URL}/v$${tag}/${RELEASE_ARCHIVE_NAME}_$${tag}_Windows_amd64.tar.gz" >/dev/null 2>&1 ;\
(cd ${VERIFY_TMP_DIR} && exec sha256sum --ignore-missing -c checksums.txt) ;\
rm -r "${VERIFY_TMP_DIR}"
4 changes: 4 additions & 0 deletions cosign.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1WWDBE9BWad6LQyWg19q4EECmuvT
CXFKwKNMfBPTLZrDqvmoH0Uc8GRKdQOlLGGDDbISd/Lj8OP6ui1SgjMC6g==
-----END PUBLIC KEY-----

0 comments on commit 972b460

Please sign in to comment.