From 0a19803bfad8ec9e1bf9e192181a307077263503 Mon Sep 17 00:00:00 2001 From: Bernd Ahlers Date: Mon, 5 Dec 2022 13:50:47 +0100 Subject: [PATCH] Release build improvements (#456) * Update chocolatey image to 1.2.0 * Copy graylog-sidecar.exe into dist/pkg so it gets uploaded * Only set chocolatey API key for the push stage * Add GitHub release stage * Add pipeline steps to sign Windows binaries * Fix jenkins.groovy stage structure * Sign graylog-sidecar.exe before building packages * Use correct Makefile targets for signing * Fix paths for 32bit Windows binaries * Don't add build targets as dependency to sign target We sign in a container that doesn't have the full build toolchain. * Set reuseNode to true for the codesign image Otherwise the build artifacts are not available in the container. * Set environment variable for the codesign tool * Sign the Windows installer .exe * Create a SHA256 checksum file for all artifacts * Use curl with -fsSL options * Add revision to Chocolatey package version * Fix prerelease versino format for Chocolatey --- Makefile | 22 ++++++- dist/chocolatey/gensha.sh | 2 - docker/Dockerfile.chocolatey | 2 +- jenkins.groovy | 116 ++++++++++++++++++++++++++++++++++- 4 files changed, 137 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index adac4a8..c5d7cb1 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,8 @@ BUILD_OPTS = -ldflags "-s -X github.com/Graylog2/collector-sidecar/common.GitRev TEST_SUITE = \ github.com/Graylog2/collector-sidecar/common +WINDOWS_INSTALLER_VERSION = $(COLLECTOR_VERSION)-$(COLLECTOR_REVISION)$(subst -,.,$(COLLECTOR_VERSION_SUFFIX)) + all: build fmt: ## Run gofmt @@ -81,6 +83,16 @@ build-windows32: install-goversioninfo ## Build sidecar binary for Windows 32bit $(GOVERSIONINFO_BIN) -product-version="$(COLLECTOR_VERSION)-$(COLLECTOR_REVISION)" -ver-major="$(COLLECTOR_VERSION_MAJOR)" -product-ver-minor="$(COLLECTOR_VERSION_MINOR)" -product-ver-patch="$(COLLECTOR_VERSION_PATCH)" -product-ver-build="$(COLLECTOR_REVISION)" -file-version="$(COLLECTOR_VERSION)-$(COLLECTOR_REVISION)" -ver-major="$(COLLECTOR_VERSION_MAJOR)" -ver-minor="$(COLLECTOR_VERSION_MINOR)" -ver-patch="$(COLLECTOR_VERSION_PATCH)" -ver-build="$(COLLECTOR_REVISION)" -o resource_windows.syso GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc $(GO) build $(BUILD_OPTS) -pkgdir $(GOPATH)/go_win32 -v -o build/$(COLLECTOR_VERSION)/windows/386/graylog-sidecar.exe +sign-binaries: sign-binary-windows-amd64 sign-binary-windows-386 + +sign-binary-windows-amd64: + # This needs to run in a Docker container with the graylog/internal-codesigntool image + codesigntool sign build/$(COLLECTOR_VERSION)/windows/amd64/graylog-sidecar.exe + +sign-binary-windows-386: + # This needs to run in a Docker container with the graylog/internal-codesigntool image + codesigntool sign build/$(COLLECTOR_VERSION)/windows/386/graylog-sidecar.exe + ## Adds version info to Windows executable install-goversioninfo: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@latest @@ -110,12 +122,20 @@ package-linux32: ## Create Linux i386 system package package-windows: prepare-package ## Create Windows installer @mkdir -p dist/pkg + cp build/$(COLLECTOR_VERSION)/windows/amd64/graylog-sidecar.exe dist/pkg/graylog-sidecar-$(COLLECTOR_VERSION)$(COLLECTOR_VERSION_SUFFIX)-amd64.exe + cp build/$(COLLECTOR_VERSION)/windows/386/graylog-sidecar.exe dist/pkg/graylog-sidecar-$(COLLECTOR_VERSION)$(COLLECTOR_VERSION_SUFFIX)-386.exe makensis -DVERSION=$(COLLECTOR_VERSION) -DVERSION_SUFFIX=$(COLLECTOR_VERSION_SUFFIX) -DREVISION=$(COLLECTOR_REVISION) dist/recipe.nsi +sign-windows-installer: + # This needs to run in a Docker container with the graylog/internal-codesigntool image + codesigntool sign dist/pkg/graylog_sidecar_installer_$(WINDOWS_INSTALLER_VERSION).exe + package-chocolatey: ## Create Chocolatey .nupkg file # This needs to run in a Docker container based on the Dockerfile.chocolatey image! dist/chocolatey/gensha.sh $(COLLECTOR_VERSION) $(COLLECTOR_REVISION) $(COLLECTOR_VERSION_SUFFIX) - cd dist/chocolatey && choco pack graylog-sidecar.nuspec --version $(COLLECTOR_VERSION)$(COLLECTOR_VERSION_SUFFIX) --out ../pkg + # The fourth number in Chocolatey (NuGet) is the revision. + # See: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#where-nugetversion-diverges-from-semantic-versioning + cd dist/chocolatey && choco pack graylog-sidecar.nuspec --version $(COLLECTOR_VERSION).$(COLLECTOR_REVISION)$(subst .,,$(COLLECTOR_VERSION_SUFFIX)) --out ../pkg push-chocolatey: ## Push Chocolatey .nupkg file # This needs to run in a Docker container based on the Dockerfile.chocolatey image! diff --git a/dist/chocolatey/gensha.sh b/dist/chocolatey/gensha.sh index 6345ec1..42b1f12 100755 --- a/dist/chocolatey/gensha.sh +++ b/dist/chocolatey/gensha.sh @@ -18,5 +18,3 @@ sed -e "s,%%CHECKSUM%%,$COLLECTOR_CHECKSUM,g" \ -e "s,%%URL%%,$version_url,g" \ "dist/chocolatey/tools/chocolateyinstall.ps1.template" \ > "dist/chocolatey/tools/chocolateyinstall.ps1" - -find dist/pkg -name "graylog_sidecar_installer*.exe" -exec /bin/bash -c "sha256sum {} | cut -d' ' -f1 > {}.sha256.txt" \; diff --git a/docker/Dockerfile.chocolatey b/docker/Dockerfile.chocolatey index 1808e5d..9909463 100644 --- a/docker/Dockerfile.chocolatey +++ b/docker/Dockerfile.chocolatey @@ -1,4 +1,4 @@ -FROM chocolatey/choco:v1.1.0 +FROM chocolatey/choco:v1.2.0 # The choco binary wants to write to /opt/chocolatey and Jenkins is running # the container as non-root user. diff --git a/jenkins.groovy b/jenkins.groovy index f82d8ec..689dec8 100644 --- a/jenkins.groovy +++ b/jenkins.groovy @@ -18,7 +18,6 @@ pipeline { GOPATH = '/home/jenkins/go' GO15VENDOREXPERIMENT=1 - CHOCO_API_KEY = credentials('chocolatey-api-key') } stages @@ -47,6 +46,37 @@ pipeline } } + // Sign the Windows binaries before we build the installer .exe to + // ensure that the signed graylog-sidecar.exe binaries are included + // in the installer. + stage('Sign Windows Binaries') + { + agent + { + docker + { + image 'graylog/internal-codesigntool:latest' + args '-u jenkins:jenkins' + registryCredentialsId 'docker-hub' + alwaysPull true + reuseNode true + } + } + + environment + { + CODESIGN_USER = credentials('codesign-user') + CODESIGN_PASS = credentials('codesign-pass') + CODESIGN_TOTP_SECRET = credentials('codesign-totp-secret') + CODESIGN_CREDENTIAL_ID = credentials('codesign-credential-id') + } + + steps + { + sh 'make sign-binaries' + } + } + stage('Package') { agent @@ -65,6 +95,34 @@ pipeline } } + stage('Sign Windows Installer') + { + agent + { + docker + { + image 'graylog/internal-codesigntool:latest' + args '-u jenkins:jenkins' + registryCredentialsId 'docker-hub' + alwaysPull false // We did that in the previous sign stage + reuseNode true + } + } + + environment + { + CODESIGN_USER = credentials('codesign-user') + CODESIGN_PASS = credentials('codesign-pass') + CODESIGN_TOTP_SECRET = credentials('codesign-totp-secret') + CODESIGN_CREDENTIAL_ID = credentials('codesign-credential-id') + } + + steps + { + sh 'make sign-windows-installer' + } + } + stage('Chocolatey Pack') { agent @@ -85,6 +143,17 @@ pipeline } } + stage('Create Checksums') + { + steps + { + dir('dist/pkg') + { + sh 'sha256sum * | tee CHECKSUMS-SHA256.txt' + } + } + } + stage('Chocolatey Push') { when @@ -104,6 +173,11 @@ pipeline } } + environment + { + CHOCO_API_KEY = credentials('chocolatey-api-key') + } + steps { sh 'make push-chocolatey' @@ -130,6 +204,46 @@ pipeline ) } } + + stage('GitHub Release') + { + when + { + buildingTag() + } + + environment + { + GITHUB_CREDS = credentials('github-access-token') + REPO_API_URL = 'https://api.github.com/repos/Graylog2/collector-sidecar' + } + + steps + { + echo "Releasing ${env.TAG_NAME} to GitHub..." + + script + { + def RELEASE_DATA = sh returnStdout: true, script: "curl -fsSL --user \"$GITHUB_CREDS\" --data \'{ \"tag_name\": \"${TAG_NAME}\", \"name\": \"${TAG_NAME}\", \"body\": \"Insert changes here.\", \"draft\": true }\' $REPO_API_URL/releases" + def props = readJSON text: RELEASE_DATA + env.RELEASE_ID = props.id + + sh '''#!/bin/bash + set -xeo pipefail + + for file in dist/pkg/*; do + name="$(basename "$file")" + + curl -fsSL \ + -H "Authorization: token $GITHUB_CREDS" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@$file" \ + "$REPO_API_URL/releases/$RELEASE_ID/assets?name=$name" + done + ''' + } + } + } } post