build syncthing macos release on ffmini, validate signing
custom release / build-custom-release (push) Failing after 1m12s
custom release / build-custom-release (push) Failing after 1m12s
This commit is contained in:
@@ -25,7 +25,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-custom-release:
|
build-custom-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ffmini_macos_arm64
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -51,6 +51,26 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
|
||||||
|
- name: Import Developer ID certificate
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
keychain_path="$RUNNER_TEMP/syncthing-release-signing.keychain-db"
|
||||||
|
keychain_password="$(openssl rand -hex 24)"
|
||||||
|
certificate_path="$RUNNER_TEMP/developer-id-application.p12"
|
||||||
|
|
||||||
|
printf '%s' "$DEVELOPER_ID_APPLICATION_P12_BASE64" | base64 -D > "$certificate_path"
|
||||||
|
security create-keychain -p "$keychain_password" "$keychain_path"
|
||||||
|
security set-keychain-settings -lut 21600 "$keychain_path"
|
||||||
|
security unlock-keychain -p "$keychain_password" "$keychain_path"
|
||||||
|
security import "$certificate_path" -k "$keychain_path" -P "$DEVELOPER_ID_APPLICATION_P12_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
|
||||||
|
security list-keychains -d user -s "$keychain_path" $(security list-keychains -d user | sed 's/[ "]//g')
|
||||||
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$keychain_password" "$keychain_path"
|
||||||
|
|
||||||
|
echo "CUSTOM_RELEASE_KEYCHAIN_PATH=$keychain_path" >> "$GITHUB_ENV"
|
||||||
|
env:
|
||||||
|
DEVELOPER_ID_APPLICATION_P12_BASE64: ${{ secrets.DEVELOPER_ID_APPLICATION_P12_BASE64 }}
|
||||||
|
DEVELOPER_ID_APPLICATION_P12_PASSWORD: ${{ secrets.DEVELOPER_ID_APPLICATION_P12_PASSWORD }}
|
||||||
|
|
||||||
- name: Build patched Syncthing release
|
- name: Build patched Syncthing release
|
||||||
run: ./scripts/update-custom-release.sh
|
run: ./scripts/update-custom-release.sh
|
||||||
env:
|
env:
|
||||||
@@ -59,7 +79,15 @@ jobs:
|
|||||||
CUSTOM_RELEASE_PUSH: "1"
|
CUSTOM_RELEASE_PUSH: "1"
|
||||||
CUSTOM_RELEASE_PUSH_BRANCH: "0"
|
CUSTOM_RELEASE_PUSH_BRANCH: "0"
|
||||||
CUSTOM_RELEASE_REMOTE: origin
|
CUSTOM_RELEASE_REMOTE: origin
|
||||||
CUSTOM_RELEASE_BUILDS: "darwin/amd64/zip darwin/arm64/zip linux/amd64/tar linux/arm64/tar"
|
CUSTOM_RELEASE_BUILDS: "darwin/arm64/zip/1 linux/amd64/tar/0 linux/arm64/tar/0"
|
||||||
CUSTOM_RELEASE_CGO_ENABLED: "0"
|
CUSTOM_RELEASE_CODESIGN_IDENTITY: "Developer ID Application: Felix Foertsch (NG5W75WE8U)"
|
||||||
|
CUSTOM_RELEASE_CODESIGN_TEAM_ID: "NG5W75WE8U"
|
||||||
CUSTOM_RELEASE_CREATE_GITEA_RELEASE: "1"
|
CUSTOM_RELEASE_CREATE_GITEA_RELEASE: "1"
|
||||||
CUSTOM_RELEASE_TEA_REPO: felixfoertsch/syncthing
|
CUSTOM_RELEASE_TEA_REPO: felixfoertsch/syncthing
|
||||||
|
|
||||||
|
- name: Delete temporary keychain
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
if [ -n "${CUSTOM_RELEASE_KEYCHAIN_PATH:-}" ]; then
|
||||||
|
security delete-keychain "$CUSTOM_RELEASE_KEYCHAIN_PATH" || true
|
||||||
|
fi
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||||
|
WORKFLOW="$REPO_ROOT/.gitea/workflows/custom-release.yml"
|
||||||
|
RELEASE_SCRIPT="$REPO_ROOT/scripts/update-custom-release.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "custom release runs as one job on ffmini macos runner" {
|
||||||
|
run rg -n 'runs-on:[[:space:]]*ffmini_macos_arm64' "$WORKFLOW"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'ubuntu-latest' "$WORKFLOW"
|
||||||
|
[ "$status" -ne 0 ]
|
||||||
|
|
||||||
|
run rg -n 'actions/upload-artifact' "$WORKFLOW"
|
||||||
|
[ "$status" -ne 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "custom release workflow imports developer id signing material into temporary keychain" {
|
||||||
|
run rg -n 'DEVELOPER_ID_APPLICATION_P12_BASE64' "$WORKFLOW"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'DEVELOPER_ID_APPLICATION_P12_PASSWORD' "$WORKFLOW"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'security create-keychain' "$WORKFLOW"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'security import' "$WORKFLOW"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'security delete-keychain' "$WORKFLOW"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "custom release carries per-target cgo mode" {
|
||||||
|
run rg -n 'darwin/arm64/zip/1' "$WORKFLOW" "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'linux/amd64/tar/0' "$WORKFLOW" "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'CUSTOM_RELEASE_CGO_ENABLED' "$WORKFLOW"
|
||||||
|
[ "$status" -ne 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "custom release signs darwin assets with hardened runtime and timestamp" {
|
||||||
|
run rg -n 'codesign .*--options runtime .*--timestamp' "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'Developer ID Application' "$WORKFLOW" "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'CUSTOM_RELEASE_CODESIGN_IDENTITY' "$WORKFLOW" "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "custom release validates darwin binaries before publishing" {
|
||||||
|
run rg -n 'modernc-sqlite' "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'codesign --verify --strict --verbose=2' "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'TeamIdentifier=NG5W75WE8U|TeamIdentifier.*NG5W75WE8U' "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
run rg -n 'spctl -a -vv --type execute' "$RELEASE_SCRIPT"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
@@ -12,7 +12,9 @@ dist_dir="${CUSTOM_RELEASE_DIST_DIR:-dist}"
|
|||||||
target="${CUSTOM_RELEASE_TARGET:-syncthing}"
|
target="${CUSTOM_RELEASE_TARGET:-syncthing}"
|
||||||
archive_kind="${CUSTOM_RELEASE_ARCHIVE:-tar}"
|
archive_kind="${CUSTOM_RELEASE_ARCHIVE:-tar}"
|
||||||
build_specs="${CUSTOM_RELEASE_BUILDS:-}"
|
build_specs="${CUSTOM_RELEASE_BUILDS:-}"
|
||||||
cgo_enabled="${CUSTOM_RELEASE_CGO_ENABLED:-0}"
|
default_cgo_enabled="${CUSTOM_RELEASE_CGO_ENABLED:-0}"
|
||||||
|
codesign_identity="${CUSTOM_RELEASE_CODESIGN_IDENTITY:-}"
|
||||||
|
codesign_team_id="${CUSTOM_RELEASE_CODESIGN_TEAM_ID:-NG5W75WE8U}"
|
||||||
push_release="${CUSTOM_RELEASE_PUSH:-0}"
|
push_release="${CUSTOM_RELEASE_PUSH:-0}"
|
||||||
push_branch="${CUSTOM_RELEASE_PUSH_BRANCH:-0}"
|
push_branch="${CUSTOM_RELEASE_PUSH_BRANCH:-0}"
|
||||||
push_remote="${CUSTOM_RELEASE_REMOTE:-origin}"
|
push_remote="${CUSTOM_RELEASE_REMOTE:-origin}"
|
||||||
@@ -148,6 +150,14 @@ rebuild_assets_once() {
|
|||||||
assets_rebuilt=1
|
assets_rebuilt=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
format_build_specs() {
|
||||||
|
local spec
|
||||||
|
|
||||||
|
for spec in $build_specs; do
|
||||||
|
printf -- '- %s\n' "$spec"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
build_release() {
|
build_release() {
|
||||||
local custom_tag="$1"
|
local custom_tag="$1"
|
||||||
|
|
||||||
@@ -170,7 +180,7 @@ build_release() {
|
|||||||
Syncthing $upstream_tag with the local patches applied.
|
Syncthing $upstream_tag with the local patches applied.
|
||||||
|
|
||||||
Builds:
|
Builds:
|
||||||
$(printf -- '- %s\n' $build_specs)
|
$(format_build_specs)
|
||||||
|
|
||||||
Patches:
|
Patches:
|
||||||
$(printf -- '- %s\n' "${patch_files[@]}")
|
$(printf -- '- %s\n' "${patch_files[@]}")
|
||||||
@@ -197,9 +207,11 @@ build_one() {
|
|||||||
local goos
|
local goos
|
||||||
local goarch
|
local goarch
|
||||||
local kind
|
local kind
|
||||||
|
local cgo_enabled
|
||||||
|
|
||||||
IFS=/ read -r goos goarch kind <<< "$spec"
|
IFS=/ read -r goos goarch kind cgo_enabled <<< "$spec"
|
||||||
[[ -n "$goos" && -n "$goarch" && -n "$kind" ]] || die "invalid build spec: $spec"
|
[[ -n "$goos" && -n "$goarch" && -n "$kind" ]] || die "invalid build spec: $spec"
|
||||||
|
cgo_enabled="${cgo_enabled:-$default_cgo_enabled}"
|
||||||
|
|
||||||
log "Building $target for $goos/$goarch as $kind with CGO_ENABLED=$cgo_enabled"
|
log "Building $target for $goos/$goarch as $kind with CGO_ENABLED=$cgo_enabled"
|
||||||
|
|
||||||
@@ -207,10 +219,16 @@ build_one() {
|
|||||||
tar|zip)
|
tar|zip)
|
||||||
local archive
|
local archive
|
||||||
archive="$(CGO_ENABLED="$cgo_enabled" go run build.go -version "$custom_tag" -goos "$goos" -goarch "$goarch" "$kind" "$target" | tail -n 1)"
|
archive="$(CGO_ENABLED="$cgo_enabled" go run build.go -version "$custom_tag" -goos "$goos" -goarch "$goarch" "$kind" "$target" | tail -n 1)"
|
||||||
|
if [[ "$goos" == "darwin" ]]; then
|
||||||
|
sign_and_validate_darwin_archive "$archive" "$kind"
|
||||||
|
fi
|
||||||
mv "$archive" "$dist_dir/"
|
mv "$archive" "$dist_dir/"
|
||||||
;;
|
;;
|
||||||
binary)
|
binary)
|
||||||
CGO_ENABLED="$cgo_enabled" go run build.go -version "$custom_tag" -goos "$goos" -goarch "$goarch" -build-out "$dist_dir/$target-$goos-$goarch" build "$target"
|
CGO_ENABLED="$cgo_enabled" go run build.go -version "$custom_tag" -goos "$goos" -goarch "$goarch" -build-out "$dist_dir/$target-$goos-$goarch" build "$target"
|
||||||
|
if [[ "$goos" == "darwin" ]]; then
|
||||||
|
sign_and_validate_darwin_binary "$dist_dir/$target-$goos-$goarch"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
die "unknown build archive kind in $spec"
|
die "unknown build archive kind in $spec"
|
||||||
@@ -218,6 +236,91 @@ build_one() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_release_binary() {
|
||||||
|
local root="$1"
|
||||||
|
local candidate
|
||||||
|
|
||||||
|
while IFS= read -r candidate; do
|
||||||
|
if [[ -x "$candidate" ]]; then
|
||||||
|
printf '%s\n' "$candidate"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done < <(find "$root" -type f -name "$target")
|
||||||
|
|
||||||
|
die "could not find executable $target in $root"
|
||||||
|
}
|
||||||
|
|
||||||
|
sign_and_validate_darwin_archive() {
|
||||||
|
local archive="$1"
|
||||||
|
local kind="$2"
|
||||||
|
local tmp
|
||||||
|
local archive_abs
|
||||||
|
local binary
|
||||||
|
|
||||||
|
[[ -n "$codesign_identity" ]] || die "CUSTOM_RELEASE_CODESIGN_IDENTITY is required for darwin builds"
|
||||||
|
|
||||||
|
tmp="$(mktemp -d)"
|
||||||
|
archive_abs="$(cd "$(dirname "$archive")" && pwd -P)/$(basename "$archive")"
|
||||||
|
case "$kind" in
|
||||||
|
zip)
|
||||||
|
unzip -q "$archive_abs" -d "$tmp"
|
||||||
|
;;
|
||||||
|
tar)
|
||||||
|
tar -xf "$archive_abs" -C "$tmp"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
die "cannot sign archive kind $kind"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
binary="$(find_release_binary "$tmp")"
|
||||||
|
sign_and_validate_darwin_binary "$binary"
|
||||||
|
|
||||||
|
rm -f "$archive_abs"
|
||||||
|
case "$kind" in
|
||||||
|
zip)
|
||||||
|
(
|
||||||
|
cd "$tmp"
|
||||||
|
zip -qr "$archive_abs" .
|
||||||
|
)
|
||||||
|
;;
|
||||||
|
tar)
|
||||||
|
(
|
||||||
|
cd "$tmp"
|
||||||
|
tar -czf "$archive_abs" .
|
||||||
|
)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
rm -rf "$tmp"
|
||||||
|
}
|
||||||
|
|
||||||
|
sign_and_validate_darwin_binary() {
|
||||||
|
local binary="$1"
|
||||||
|
local version_output
|
||||||
|
local codesign_details
|
||||||
|
|
||||||
|
[[ -n "$codesign_identity" ]] || die "CUSTOM_RELEASE_CODESIGN_IDENTITY is required for darwin builds"
|
||||||
|
|
||||||
|
codesign --force --sign "$codesign_identity" --options runtime --timestamp "$binary"
|
||||||
|
|
||||||
|
version_output="$("$binary" --version)"
|
||||||
|
if [[ "$version_output" == *modernc-sqlite* ]]; then
|
||||||
|
die "darwin build unexpectedly reports [modernc-sqlite]: $version_output"
|
||||||
|
fi
|
||||||
|
|
||||||
|
codesign --verify --strict --verbose=2 "$binary"
|
||||||
|
codesign_details="$(codesign -dv --verbose=4 "$binary" 2>&1)"
|
||||||
|
if [[ "$codesign_team_id" == "NG5W75WE8U" && "$codesign_details" != *"TeamIdentifier=NG5W75WE8U"* ]]; then
|
||||||
|
printf '%s\n' "$codesign_details" >&2
|
||||||
|
die "darwin build is not signed by TeamIdentifier=NG5W75WE8U"
|
||||||
|
fi
|
||||||
|
if [[ "$codesign_details" != *"TeamIdentifier=$codesign_team_id"* ]]; then
|
||||||
|
printf '%s\n' "$codesign_details" >&2
|
||||||
|
die "darwin build is not signed by TeamIdentifier=$codesign_team_id"
|
||||||
|
fi
|
||||||
|
spctl -a -vv --type execute "$binary"
|
||||||
|
}
|
||||||
|
|
||||||
push_refs() {
|
push_refs() {
|
||||||
local branch="$1"
|
local branch="$1"
|
||||||
local custom_tag="$2"
|
local custom_tag="$2"
|
||||||
|
|||||||
Reference in New Issue
Block a user