diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8d7cc583..82d7f9f3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -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' || '' }}" diff --git a/.github/workflows/goreleaser-cd.yml b/.github/workflows/goreleaser-cd.yml index d54924bf..430279c3 100644 --- a/.github/workflows/goreleaser-cd.yml +++ b/.github/workflows/goreleaser-cd.yml @@ -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' || '' }}" @@ -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 @@ -106,16 +109,20 @@ jobs: uses: WyriHaximus/github-action-get-previous-tag@v1 env: INPUT_PREFIX: v + - name: Install Cosign + uses: sigstore/cosign-installer@v3.6.0 - 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 }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index fc77b0e6..61a99516 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -5,6 +5,8 @@ partial: by: goos +version: 2 + before: hooks: - go mod tidy @@ -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. @@ -62,7 +64,7 @@ builds: archives: - id: plural-cli - builds: [ plural-cli ] + builds: [plural-cli] name_template: >- {{ .ProjectName }}_{{ .Version }}_ {{- title .Os }}_ @@ -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 @@ -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: | @@ -106,7 +119,7 @@ git: brews: - name: plural - ids: [ plural-cli ] + ids: [plural-cli] repository: owner: pluralsh name: homebrew-plural @@ -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. diff --git a/Makefile b/Makefile index 18925767..0fe2bfcc 100644 --- a/Makefile +++ b/Makefile @@ -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 @@ -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; \ @@ -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 @@ -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}" diff --git a/cosign.pub b/cosign.pub new file mode 100644 index 00000000..3006317f --- /dev/null +++ b/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1WWDBE9BWad6LQyWg19q4EECmuvT +CXFKwKNMfBPTLZrDqvmoH0Uc8GRKdQOlLGGDDbISd/Lj8OP6ui1SgjMC6g== +-----END PUBLIC KEY-----