Skip to content
Open
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
7 changes: 7 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,10 @@ jobs:
# Token with contents + pull-requests write on sumup/homebrew-cli.
# GITHUB_TOKEN cannot push cask updates to a different repository.
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
# Apple Developer ID + notary credentials.
# Required for Gatekeeper-clean Homebrew installs on macOS.
MACOS_SIGN_P12: ${{ secrets.MACOS_SIGN_P12 }}
MACOS_SIGN_PASSWORD: ${{ secrets.MACOS_SIGN_PASSWORD }}
MACOS_NOTARY_KEY: ${{ secrets.MACOS_NOTARY_KEY }}
MACOS_NOTARY_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }}
MACOS_NOTARY_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }}
32 changes: 14 additions & 18 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,6 @@ builds:
ldflags:
- -s -w -X github.com/sumup/sumup-cli/internal/buildinfo.Version={{ .Version }} -X github.com/sumup/sumup-cli/internal/buildinfo.Commit={{ .Commit }} -X github.com/sumup/sumup-cli/internal/buildinfo.Date={{ .Date }}

# Enable when signing credentials are configured in CI.
# hooks:
# post:
# - cmd: >-
# {{ if eq .Os "darwin" }}./scripts/sign-macos.sh '{{ .Path }}'{{ else }}echo{{ end }}
# output: true
# - cmd: >-
# {{ if eq .Os "windows" }}pwsh ./scripts/sign-windows.ps1 '{{ .Path }}'{{ else }}echo{{ end }}
# output: true

archives:
- id: linux-archive
ids: [linux]
Expand Down Expand Up @@ -105,6 +95,20 @@ archives:
checksum:
name_template: checksums.txt

# Sign and notarize macOS binaries when Apple credentials are present.
# Homebrew installs require notarized binaries (no quarantine bypass in the cask).
notarize:
macos:
- enabled: '{{ isEnvSet "MACOS_SIGN_P12" }}'
ids: [macos]
sign:
certificate: "{{ .Env.MACOS_SIGN_P12 }}"
password: "{{ .Env.MACOS_SIGN_PASSWORD }}"
notarize:
issuer_id: "{{ .Env.MACOS_NOTARY_ISSUER_ID }}"
key_id: "{{ .Env.MACOS_NOTARY_KEY_ID }}"
key: "{{ .Env.MACOS_NOTARY_KEY }}"

# Publishes Casks/sumup.rb to the public tap sumup/homebrew-cli.
# Requires HOMEBREW_TAP_GITHUB_TOKEN with write access to that repository.
homebrew_casks:
Expand All @@ -122,14 +126,6 @@ homebrew_casks:
homepage: https://developer.sumup.com
description: Command line tool for interacting with SumUp APIs.
license: Apache-2.0
# Binaries are not yet notarized; clear quarantine so Gatekeeper does not
# block the unsigned CLI. Remove this hook once macOS signing is enabled.
hooks:
post:
install: |
if OS.mac?
system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/sumup"]
end
skip_upload: auto

changelog:
Expand Down
25 changes: 11 additions & 14 deletions scripts/sign-macos.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/usr/bin/env bash
# Local helper for macOS signing. Release builds use GoReleaser's notarize
# section with MACOS_SIGN_P12 / MACOS_SIGN_PASSWORD / MACOS_NOTARY_* secrets.
set -euo pipefail

binary_path="${1:-}"
Expand All @@ -7,18 +9,13 @@ if [[ -z "$binary_path" ]]; then
exit 1
fi

# Placeholder script for future macOS signing and notarization.
# Expected env vars once enabled:
# - APPLE_CERT_BASE64
# - APPLE_CERT_PASSWORD
# - APPLE_TEAM_ID
# - APPLE_ID
# - APPLE_APP_SPECIFIC_PASSWORD
#
# Example (to enable later):
# security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
# echo "$APPLE_CERT_BASE64" | base64 --decode > cert.p12
# security import cert.p12 -k build.keychain -P "$APPLE_CERT_PASSWORD" -T /usr/bin/codesign
# codesign --force --timestamp --options runtime --sign "Developer ID Application: ..." "$binary_path"
if [[ -z "${MACOS_SIGN_IDENTITY:-}" ]]; then
echo "MACOS_SIGN_IDENTITY is not set; skipping codesign for $binary_path" >&2
exit 0
fi

codesign --force --timestamp --options runtime \
--sign "$MACOS_SIGN_IDENTITY" \
"$binary_path"

echo "macOS signing is currently disabled. Skipping: $binary_path"
echo "Signed $binary_path with $MACOS_SIGN_IDENTITY"
61 changes: 52 additions & 9 deletions scripts/sign-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,56 @@ param(

$ErrorActionPreference = "Stop"

# Placeholder script for future Windows Authenticode signing.
# Expected env vars once enabled:
# - WINDOWS_CERT_BASE64
# - WINDOWS_CERT_PASSWORD
#
# Example (to enable later):
# [IO.File]::WriteAllBytes("cert.pfx", [Convert]::FromBase64String($env:WINDOWS_CERT_BASE64))
# signtool sign /f cert.pfx /p $env:WINDOWS_CERT_PASSWORD /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 $BinaryPath
# Cross-compiled Windows binaries are signed only when this hook runs on Windows
# with Authenticode credentials available.
if (-not $IsWindows) {
Write-Output "Not running on Windows; skipping Authenticode signing for $BinaryPath"
exit 0
}

Write-Output "Windows signing is currently disabled. Skipping: $BinaryPath"
if (-not $env:WINDOWS_CERT_BASE64 -or -not $env:WINDOWS_CERT_PASSWORD) {
Write-Output "WINDOWS_CERT_BASE64 / WINDOWS_CERT_PASSWORD not set; skipping Authenticode signing for $BinaryPath"
exit 0
}

$certPath = Join-Path ([System.IO.Path]::GetTempPath()) ("sumup-windows-" + [guid]::NewGuid().ToString() + ".pfx")
try {
[IO.File]::WriteAllBytes($certPath, [Convert]::FromBase64String($env:WINDOWS_CERT_BASE64))

$signtool = $null
$candidates = @(
"${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\x64\signtool.exe",
"${env:ProgramFiles}\Windows Kits\10\bin\*\x64\signtool.exe"
)
foreach ($pattern in $candidates) {
$match = Get-Item $pattern -ErrorAction SilentlyContinue | Sort-Object FullName -Descending | Select-Object -First 1
if ($match) {
$signtool = $match.FullName
break
}
}
if (-not $signtool) {
$signtool = Get-Command signtool.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source
}
if (-not $signtool) {
throw "signtool.exe not found; install Windows SDK signing tools"
}

& $signtool sign `
/f $certPath `
/p $env:WINDOWS_CERT_PASSWORD `
/fd SHA256 `
/tr http://timestamp.digicert.com `
/td SHA256 `
$BinaryPath
if ($LASTEXITCODE -ne 0) {
throw "signtool failed with exit code $LASTEXITCODE"
}

Write-Output "Signed $BinaryPath"
}
finally {
if (Test-Path $certPath) {
Remove-Item -Force $certPath
}
}
Loading