From dea2cd5fe1c886c783a981603e6007184c97c5ce Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Tue, 5 Dec 2023 15:24:50 -0500 Subject: [PATCH 1/9] Create HSM testing workflow This commit is an initial prototype based on the deployment workflow, using the Azure Code Signing service to sign Windows .exe and .msi files. These changes have been isolated as much as possible to not affect existing deployment workflows while also working around design issues with how GitHub CLI workflow works with GoReleaser and now with ACS support. The biggest smell was over whether to break from using GoReleaser or have GoReleaser control as much about the release process as it has been versus opening / signing / archiving the resulting GoReleaser artifacts; needless to say, the latter was chosen for expedience as well as leaning into officially supported solutions. --- .github/workflows/hsm-testing.yml | 127 ++++++++++++++++++++++++++++++ .goreleaser-hsm.yml | 93 ++++++++++++++++++++++ script/release-hsm | 120 ++++++++++++++++++++++++++++ 3 files changed, 340 insertions(+) create mode 100644 .github/workflows/hsm-testing.yml create mode 100644 .goreleaser-hsm.yml create mode 100755 script/release-hsm diff --git a/.github/workflows/hsm-testing.yml b/.github/workflows/hsm-testing.yml new file mode 100644 index 000000000..31e31abab --- /dev/null +++ b/.github/workflows/hsm-testing.yml @@ -0,0 +1,127 @@ +name: HSM Testing +run-name: ${{ inputs.tag_name }} / go ${{ inputs.go_version }} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +permissions: + contents: write + +on: + workflow_dispatch: + inputs: + tag_name: + required: true + type: string + go_version: + default: "1.21" + type: string + +jobs: + windows: + runs-on: windows-latest + environment: production + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: ${{ inputs.go_version }} + - name: Install GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + version: "~1.17.1" + install-only: true + - name: Build release binaries + shell: bash + env: + TAG_NAME: ${{ inputs.tag_name }} + run: script/release-hsm --local "$TAG_NAME" --platform windows --config .goreleaser-hsm.yml + + # As official Azure HSM support for signing Windows .exe binaries is in the form of an action, + # we must unzip the archives created by GoReleaser, sign the binaries, and then re-zip them. + # This choice was due to the fact that GoReleaser produces + - name: Expand goreleaser archives for signing + shell: bash + run: | + for ZIP_FILE in dist/gh_*_windows_*.zip; do + unzip -d "${ZIP_FILE%.zip}" "$ZIP_FILE" + done + - name: Sign .exe release binaries + uses: azure/azure-code-signing-action@6c86237186b7eed50c9e8a3a6e42131bcc5e4601 + with: + azure-tenant-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_TENANT_ID }} + azure-client-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_CLIENT_ID }} + azure-client-secret: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO }} + endpoint: https://wus.codesigning.azure.net/ + code-signing-account-name: GitHubInc + certificate-profile-name: GitHubInc + files-folder: ${{ github.workspace }}/dist + files-folder-filter: exe + file-digest: SHA256 + timestamp-rfc3161: http://timestamp.acs.microsoft.com + timestamp-digest: SHA256 + - name: Zip goreleaser directories + shell: bash + run: | + for DIR in dist/gh_*_windows_*; do + zip -r "$DIR.zip" "$DIR" + done + + - name: Set up MSBuild + id: setupmsbuild + uses: microsoft/setup-msbuild@v1.3.1 + - name: Build MSI + shell: bash + env: + MSBUILD_PATH: ${{ steps.setupmsbuild.outputs.msbuildPath }} + run: | + for ZIP_FILE in dist/gh_*_windows_*.zip; do + MSI_NAME="$(basename "$ZIP_FILE" ".zip")" + MSI_VERSION="$(cut -d_ -f2 <<<"$MSI_NAME" | cut -d- -f1)" + case "$MSI_NAME" in + *_386 ) + source_dir="$PWD/dist/windows_windows_386" + platform="x86" + ;; + *_amd64 ) + source_dir="$PWD/dist/windows_windows_amd64_v1" + platform="x64" + ;; + *_arm64 ) + echo "skipping building MSI for arm64 because WiX 3.11 doesn't support it: https://github.com/wixtoolset/issues/issues/6141" >&2 + continue + #source_dir="$PWD/dist/windows_windows_arm64" + #platform="arm64" + ;; + * ) + printf "unsupported architecture: %s\n" "$MSI_NAME" >&2 + exit 1 + ;; + esac + "${MSBUILD_PATH}\MSBuild.exe" ./build/windows/gh.wixproj -p:SourceDir="$source_dir" -p:OutputPath="$PWD/dist" -p:OutputName="$MSI_NAME" -p:ProductVersion="${MSI_VERSION#v}" -p:Platform="$platform" + done + - name: Sign .msi release binaries + uses: azure/azure-code-signing-action@6c86237186b7eed50c9e8a3a6e42131bcc5e4601 + with: + azure-tenant-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_TENANT_ID }} + azure-client-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_CLIENT_ID }} + azure-client-secret: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO }} + endpoint: https://wus.codesigning.azure.net/ + code-signing-account-name: GitHubInc + certificate-profile-name: GitHubInc + files-folder: ${{ github.workspace }}/dist + files-folder-filter: msi + file-digest: SHA256 + timestamp-rfc3161: http://timestamp.acs.microsoft.com + timestamp-digest: SHA256 + - uses: actions/upload-artifact@v3 + with: + name: windows + if-no-files-found: error + retention-days: 7 + path: | + dist/*.zip + dist/*.msi \ No newline at end of file diff --git a/.goreleaser-hsm.yml b/.goreleaser-hsm.yml new file mode 100644 index 000000000..7d3b975a5 --- /dev/null +++ b/.goreleaser-hsm.yml @@ -0,0 +1,93 @@ +project_name: gh + +release: + prerelease: auto + draft: true # we only publish after the Windows MSI gets uploaded + name_template: "GitHub CLI {{.Version}}" + +before: + hooks: + - >- + {{ if eq .Runtime.Goos "windows" }}echo{{ end }} make manpages GH_VERSION={{.Version}} + - >- + {{ if ne .Runtime.Goos "linux" }}echo{{ end }} make completions + +builds: + - id: macos #build:macos + goos: [darwin] + goarch: [amd64, arm64] + hooks: + post: + - cmd: ./script/sign '{{ .Path }}' + output: true + binary: bin/gh + main: ./cmd/gh + ldflags: + - -s -w -X github.com/cli/cli/v2/internal/build.Version={{.Version}} -X github.com/cli/cli/v2/internal/build.Date={{time "2006-01-02"}} + + - id: linux #build:linux + goos: [linux] + goarch: [386, arm, amd64, arm64] + env: + - CGO_ENABLED=0 + binary: bin/gh + main: ./cmd/gh + ldflags: + - -s -w -X github.com/cli/cli/v2/internal/build.Version={{.Version}} -X github.com/cli/cli/v2/internal/build.Date={{time "2006-01-02"}} + + - id: windows #build:windows + goos: [windows] + goarch: [386, amd64, arm64] + binary: bin/gh + main: ./cmd/gh + ldflags: + - -s -w -X github.com/cli/cli/v2/internal/build.Version={{.Version}} -X github.com/cli/cli/v2/internal/build.Date={{time "2006-01-02"}} + +archives: + - id: linux-archive + builds: [linux] + name_template: "gh_{{ .Version }}_linux_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" + wrap_in_directory: true + format: tar.gz + rlcp: true + files: + - LICENSE + - ./share/man/man1/gh*.1 + - id: macos-archive + builds: [macos] + name_template: "gh_{{ .Version }}_macOS_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" + wrap_in_directory: true + format: zip + rlcp: true + files: + - LICENSE + - ./share/man/man1/gh*.1 + - id: windows-archive + builds: [windows] + name_template: "gh_{{ .Version }}_windows_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" + wrap_in_directory: false + format: zip + rlcp: true + files: + - LICENSE + +nfpms: #build:linux + - license: MIT + maintainer: GitHub + homepage: https://github.com/cli/cli + bindir: /usr + dependencies: + - git + description: GitHub’s official command line tool. + formats: + - deb + - rpm + contents: + - src: "./share/man/man1/gh*.1" + dst: "/usr/share/man/man1" + - src: "./share/bash-completion/completions/gh" + dst: "/usr/share/bash-completion/completions/gh" + - src: "./share/fish/vendor_completions.d/gh.fish" + dst: "/usr/share/fish/vendor_completions.d/gh.fish" + - src: "./share/zsh/site-functions/_gh" + dst: "/usr/share/zsh/site-functions/_gh" diff --git a/script/release-hsm b/script/release-hsm new file mode 100755 index 000000000..661e10853 --- /dev/null +++ b/script/release-hsm @@ -0,0 +1,120 @@ +#!/bin/bash +set -e + +print_help() { + cat < [--platform {linux|macos|windows}] [--branch ] + +To build staging binaries from the current branch: + script/release --current [--platform {linux|macos|windows}] + +To build binaries locally with goreleaser: + script/release --local --platform {linux|macos|windows} +EOF +} + +if [ $# -eq 0 ]; then + print_help >&2 + exit 1 +fi + +tag_name="" +is_local="" +do_push="" +platform="" +branch="trunk" +deploy_env="production" +goreleaser_config=".goreleaser.yml" + +while [ $# -gt 0 ]; do + case "$1" in + -h | --help ) + print_help + exit 0 + ;; + -b | --branch ) + branch="$2" + shift 2 + ;; + -c | --config ) + goreleaser_config="$2" + shift 2 + ;; + -p | --platform ) + platform="$2" + shift 2 + ;; + --local ) + is_local=1 + shift 1 + ;; + --staging ) + deploy_env="staging" + shift 1 + ;; + --current ) + deploy_env="staging" + tag_name="$(git describe --tags --abbrev=0)" + branch="$(git rev-parse --symbolic-full-name '@{upstream}' 2>/dev/null || git branch --show-current)" + branch="${branch#refs/remotes/*/}" + do_push=1 + shift 1 + ;; + -* ) + printf "unrecognized flag: %s\n" "$1" >&2 + exit 1 + ;; + * ) + tag_name="$1" + shift 1 + ;; + esac +done + +announce() { + local tmpdir="${TMPDIR:-/tmp}" + echo "$*" | sed "s:${tmpdir%/}:\$TMPDIR:" + "$@" +} + +trigger_deployment() { + announce gh workflow -R cli/cli run deployment.yml --ref "$branch" -f tag_name="$tag_name" -f environment="$deploy_env" +} + +build_local() { + local config="$goreleaser_config" + case "$platform" in + linux ) + sed '/#build:windows/,/^$/d; /#build:macos/,/^$/d' .goreleaser.yml >.goreleaser.generated.yml + config=".goreleaser.generated.yml" + ;; + macos ) + sed '/#build:windows/,/^$/d; /#build:linux/,/^$/d' .goreleaser.yml >.goreleaser.generated.yml + config=".goreleaser.generated.yml" + ;; + windows ) + sed '/#build:linux/,/^$/d; /#build:macos/,/^$/d' .goreleaser.yml >.goreleaser.generated.yml + config=".goreleaser.generated.yml" + ;; + esac + [ -z "$tag_name" ] || export GORELEASER_CURRENT_TAG="$tag_name" + announce goreleaser release -f "$config" --clean --skip-validate --skip-publish --release-notes="$(mktemp)" +} + +if [ -n "$is_local" ]; then + build_local +else + if [ -n "$do_push" ]; then + if ! git diff --quiet || ! git diff --cached --quiet; then + echo "refusing to continue due to uncomitted local changes" >&2 + exit 1 + fi + announce git push + fi + trigger_deployment + if [ "$deploy_env" = "production" ]; then + echo + echo "Go to Slack to manually approve this production deployment." + fi +fi From 5e8e645a7f9a24a18d4e287369cd4dfb63094ef9 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 8 Dec 2023 17:27:22 -0500 Subject: [PATCH 2/9] Update HSM test using Desktop approach This update leverages GitHub Desktop approach of downloading Azure Code Signing DLL and wiring it up as part of the existing signing process used by Windows builds. --- .github/workflows/deployment-hsm-testing.yml | 151 +++++++++++++++++++ .goreleaser-hsm.yml | 5 + script/sign-hsm.bat | 14 ++ 3 files changed, 170 insertions(+) create mode 100644 .github/workflows/deployment-hsm-testing.yml create mode 100644 script/sign-hsm.bat diff --git a/.github/workflows/deployment-hsm-testing.yml b/.github/workflows/deployment-hsm-testing.yml new file mode 100644 index 000000000..ba1e97c3f --- /dev/null +++ b/.github/workflows/deployment-hsm-testing.yml @@ -0,0 +1,151 @@ +name: Deployment +run-name: ${{ inputs.tag_name }} / go ${{ inputs.go_version }} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +permissions: + contents: write + +on: + workflow_dispatch: + inputs: + tag_name: + required: true + type: string + go_version: + default: "1.21" + type: string + +jobs: + windows: + runs-on: windows-latest + environment: production + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: ${{ inputs.go_version }} + - name: Install GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + version: "~1.17.1" + install-only: true + - name: Install Azure Code Signing Client + shell: pwsh + env: + ACS_DIR: ${{ runner.temp }}\acs + ACS_ZIP: ${{ runner.temp }}\acs.zip + CORRELATION_ID: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + METADATA_PATH: ${{ runner.temp }}\acs\metadata.json + run: | + Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Azure.CodeSigning.Client/1.0.38 -OutFile $Env:ACS_ZIP -Verbose + Expand-Archive $acsZip -Destination $Env:ACS_DIR acsDir -Force -Verbose + + # Replace ancient signtool in scripts with one that supports ACS + Copy-Item -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\*" -Include signtool.exe,signtool.exe.manifest,Microsoft.Windows.Build.Signing.mssign32.dll.manifest,mssign32.dll,Microsoft.Windows.Build.Signing.wintrust.dll.manifest,wintrust.dll,Microsoft.Windows.Build.Appx.AppxSip.dll.manifest,AppxSip.dll,Microsoft.Windows.Build.Appx.AppxPackaging.dll.manifest,AppxPackaging.dll,Microsoft.Windows.Build.Appx.OpcServices.dll.manifest,OpcServices.dll -Destination scripts -Verbose + + # Generate metadata file for signtool + @{ + CertificateProfileName = "GitHubInc" + CodeSigningAccountName = "GitHubInc" + CorrelationId = $Env:CORRELATION_ID + Description = "GitHub CLI" + Endpoint = "https://wus.codesigning.azure.net/ + + # Unused metadata configuration: + # AppendSignature + # DescriptionUrl + # EnhancedKeyUsage + # ExcludeAzureCliCredential + # ExcludeAzurePowerShellCredential + # ExcludeEnvironmentCredential + # ExcludeInteractiveBrowserCredential + # ExcludeManagedIdentityCredential + # ExcludeSharedTokenCacheCredential + # ExcludeVisualStudioCodeCredential + # ExcludeVisualStudioCredential + # FileDigest + # FilesCatalog + # FilesFolder + # FilesFolderDepth + # FilesFolderFilter + # FilesFolderRecurse + # GenerateDigestPath + # GenerateDigestXml + # GeneratePageHashes + # GeneratePkcs7 + # IngestDigestPath + # Pkcs7Oid + # Pkcs7Options + # SignDigest + # SuppressPageHashes + # Timeout + # TimestampDigest + # TimestampRfc3161 + } | ConvertTo-Json | Out-File -FilePath $Env:METADATA_PATH + - name: Build release binaries + shell: bash + env: + DLIB_PATH: ${{ runner.temp }}\acs\bin/x64/Azure.CodeSigning.Dlib.dll + METADATA_PATH: ${{ runner.temp }}\acs\metadata.json + TAG_NAME: ${{ inputs.tag_name }} + run: script/release-hsm --local "$TAG_NAME" --platform windows --config .goreleaser-hsm.yml + - name: Set up MSBuild + id: setupmsbuild + uses: microsoft/setup-msbuild@v1.3.1 + - name: Build MSI + shell: bash + env: + MSBUILD_PATH: ${{ steps.setupmsbuild.outputs.msbuildPath }} + run: | + for ZIP_FILE in dist/gh_*_windows_*.zip; do + MSI_NAME="$(basename "$ZIP_FILE" ".zip")" + MSI_VERSION="$(cut -d_ -f2 <<<"$MSI_NAME" | cut -d- -f1)" + case "$MSI_NAME" in + *_386 ) + source_dir="$PWD/dist/windows_windows_386" + platform="x86" + ;; + *_amd64 ) + source_dir="$PWD/dist/windows_windows_amd64_v1" + platform="x64" + ;; + *_arm64 ) + echo "skipping building MSI for arm64 because WiX 3.11 doesn't support it: https://github.com/wixtoolset/issues/issues/6141" >&2 + continue + #source_dir="$PWD/dist/windows_windows_arm64" + #platform="arm64" + ;; + * ) + printf "unsupported architecture: %s\n" "$MSI_NAME" >&2 + exit 1 + ;; + esac + "${MSBUILD_PATH}\MSBuild.exe" ./build/windows/gh.wixproj -p:SourceDir="$source_dir" -p:OutputPath="$PWD/dist" -p:OutputName="$MSI_NAME" -p:ProductVersion="${MSI_VERSION#v}" -p:Platform="$platform" + done + - name: Sign .msi release binaries + uses: azure/azure-code-signing-action@6c86237186b7eed50c9e8a3a6e42131bcc5e4601 + with: + azure-tenant-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_TENANT_ID }} + azure-client-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_CLIENT_ID }} + azure-client-secret: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO }} + endpoint: https://wus.codesigning.azure.net/ + code-signing-account-name: GitHubInc + certificate-profile-name: GitHubInc + files-folder: ${{ github.workspace }}/dist + files-folder-filter: msi + file-digest: SHA256 + timestamp-rfc3161: http://timestamp.acs.microsoft.com + timestamp-digest: SHA256 + - uses: actions/upload-artifact@v3 + with: + name: windows + if-no-files-found: error + retention-days: 7 + path: | + dist/*.zip + dist/*.msi \ No newline at end of file diff --git a/.goreleaser-hsm.yml b/.goreleaser-hsm.yml index 7d3b975a5..a48de4c7a 100644 --- a/.goreleaser-hsm.yml +++ b/.goreleaser-hsm.yml @@ -38,6 +38,11 @@ builds: - id: windows #build:windows goos: [windows] goarch: [386, amd64, arm64] + hooks: + post: + - cmd: >- + {{ if eq .Runtime.Goos "windows" }}.\script\sign-hsm{{ else }}./script/sign{{ end }} '{{ .Path }}' + output: true binary: bin/gh main: ./cmd/gh ldflags: diff --git a/script/sign-hsm.bat b/script/sign-hsm.bat new file mode 100644 index 000000000..0b3512710 --- /dev/null +++ b/script/sign-hsm.bat @@ -0,0 +1,14 @@ +@echo off + +if "%DLIB_PATH%" == "" ( + echo skipping Windows code-signing; DLIB_PATH not set + exit /b +) + +if "%METADATA_PATH%" == "" ( + echo skipping Windows code-signing; METADATA_PATH not set + exit /b +) + +REM For more information on signtool, see https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool +.\script\signtool sign /d "GitHub CLI" /fd sha256 /td sha256 /tr http://timestamp.acs.microsoft.com /v /dlib "%DLIB_PATH%" /dmdf "%METADATA_PATH%" "%1" \ No newline at end of file From 0af95d931466e77eed2a86ed5ce6ec010e642108 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 8 Dec 2023 17:29:19 -0500 Subject: [PATCH 3/9] Remove previous hsm test workflow --- .github/workflows/hsm-testing.yml | 127 ------------------------------ 1 file changed, 127 deletions(-) delete mode 100644 .github/workflows/hsm-testing.yml diff --git a/.github/workflows/hsm-testing.yml b/.github/workflows/hsm-testing.yml deleted file mode 100644 index 31e31abab..000000000 --- a/.github/workflows/hsm-testing.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: HSM Testing -run-name: ${{ inputs.tag_name }} / go ${{ inputs.go_version }} - -concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} - cancel-in-progress: true - -permissions: - contents: write - -on: - workflow_dispatch: - inputs: - tag_name: - required: true - type: string - go_version: - default: "1.21" - type: string - -jobs: - windows: - runs-on: windows-latest - environment: production - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: ${{ inputs.go_version }} - - name: Install GoReleaser - uses: goreleaser/goreleaser-action@v5 - with: - version: "~1.17.1" - install-only: true - - name: Build release binaries - shell: bash - env: - TAG_NAME: ${{ inputs.tag_name }} - run: script/release-hsm --local "$TAG_NAME" --platform windows --config .goreleaser-hsm.yml - - # As official Azure HSM support for signing Windows .exe binaries is in the form of an action, - # we must unzip the archives created by GoReleaser, sign the binaries, and then re-zip them. - # This choice was due to the fact that GoReleaser produces - - name: Expand goreleaser archives for signing - shell: bash - run: | - for ZIP_FILE in dist/gh_*_windows_*.zip; do - unzip -d "${ZIP_FILE%.zip}" "$ZIP_FILE" - done - - name: Sign .exe release binaries - uses: azure/azure-code-signing-action@6c86237186b7eed50c9e8a3a6e42131bcc5e4601 - with: - azure-tenant-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_TENANT_ID }} - azure-client-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_CLIENT_ID }} - azure-client-secret: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO }} - endpoint: https://wus.codesigning.azure.net/ - code-signing-account-name: GitHubInc - certificate-profile-name: GitHubInc - files-folder: ${{ github.workspace }}/dist - files-folder-filter: exe - file-digest: SHA256 - timestamp-rfc3161: http://timestamp.acs.microsoft.com - timestamp-digest: SHA256 - - name: Zip goreleaser directories - shell: bash - run: | - for DIR in dist/gh_*_windows_*; do - zip -r "$DIR.zip" "$DIR" - done - - - name: Set up MSBuild - id: setupmsbuild - uses: microsoft/setup-msbuild@v1.3.1 - - name: Build MSI - shell: bash - env: - MSBUILD_PATH: ${{ steps.setupmsbuild.outputs.msbuildPath }} - run: | - for ZIP_FILE in dist/gh_*_windows_*.zip; do - MSI_NAME="$(basename "$ZIP_FILE" ".zip")" - MSI_VERSION="$(cut -d_ -f2 <<<"$MSI_NAME" | cut -d- -f1)" - case "$MSI_NAME" in - *_386 ) - source_dir="$PWD/dist/windows_windows_386" - platform="x86" - ;; - *_amd64 ) - source_dir="$PWD/dist/windows_windows_amd64_v1" - platform="x64" - ;; - *_arm64 ) - echo "skipping building MSI for arm64 because WiX 3.11 doesn't support it: https://github.com/wixtoolset/issues/issues/6141" >&2 - continue - #source_dir="$PWD/dist/windows_windows_arm64" - #platform="arm64" - ;; - * ) - printf "unsupported architecture: %s\n" "$MSI_NAME" >&2 - exit 1 - ;; - esac - "${MSBUILD_PATH}\MSBuild.exe" ./build/windows/gh.wixproj -p:SourceDir="$source_dir" -p:OutputPath="$PWD/dist" -p:OutputName="$MSI_NAME" -p:ProductVersion="${MSI_VERSION#v}" -p:Platform="$platform" - done - - name: Sign .msi release binaries - uses: azure/azure-code-signing-action@6c86237186b7eed50c9e8a3a6e42131bcc5e4601 - with: - azure-tenant-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_TENANT_ID }} - azure-client-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_CLIENT_ID }} - azure-client-secret: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO }} - endpoint: https://wus.codesigning.azure.net/ - code-signing-account-name: GitHubInc - certificate-profile-name: GitHubInc - files-folder: ${{ github.workspace }}/dist - files-folder-filter: msi - file-digest: SHA256 - timestamp-rfc3161: http://timestamp.acs.microsoft.com - timestamp-digest: SHA256 - - uses: actions/upload-artifact@v3 - with: - name: windows - if-no-files-found: error - retention-days: 7 - path: | - dist/*.zip - dist/*.msi \ No newline at end of file From 4054968fc3a71ec1993405de2a4b74ab259f088f Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 8 Dec 2023 17:30:28 -0500 Subject: [PATCH 4/9] Fix Dlib DLL path Mixed up Unix and Windows path separators --- .github/workflows/deployment-hsm-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployment-hsm-testing.yml b/.github/workflows/deployment-hsm-testing.yml index ba1e97c3f..d88c1472a 100644 --- a/.github/workflows/deployment-hsm-testing.yml +++ b/.github/workflows/deployment-hsm-testing.yml @@ -90,7 +90,7 @@ jobs: - name: Build release binaries shell: bash env: - DLIB_PATH: ${{ runner.temp }}\acs\bin/x64/Azure.CodeSigning.Dlib.dll + DLIB_PATH: ${{ runner.temp }}\acs\bin\x64\Azure.CodeSigning.Dlib.dll METADATA_PATH: ${{ runner.temp }}\acs\metadata.json TAG_NAME: ${{ inputs.tag_name }} run: script/release-hsm --local "$TAG_NAME" --platform windows --config .goreleaser-hsm.yml From 4f8d2f71e47e8b2139cb8a132acabb802a088df4 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 8 Dec 2023 17:33:52 -0500 Subject: [PATCH 5/9] Moving options to metadata --- script/sign-hsm.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/sign-hsm.bat b/script/sign-hsm.bat index 0b3512710..7d0347178 100644 --- a/script/sign-hsm.bat +++ b/script/sign-hsm.bat @@ -11,4 +11,4 @@ if "%METADATA_PATH%" == "" ( ) REM For more information on signtool, see https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool -.\script\signtool sign /d "GitHub CLI" /fd sha256 /td sha256 /tr http://timestamp.acs.microsoft.com /v /dlib "%DLIB_PATH%" /dmdf "%METADATA_PATH%" "%1" \ No newline at end of file +.\script\signtool sign /fd sha256 /td sha256 /tr http://timestamp.acs.microsoft.com /v /dlib "%DLIB_PATH%" /dmdf "%METADATA_PATH%" "%1" \ No newline at end of file From 1fff21a63e504da92e8826ec1fcaa2762b98239d Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Tue, 12 Dec 2023 09:48:16 -0500 Subject: [PATCH 6/9] Fixes based on actual secret names and signtool insights --- .github/workflows/deployment-hsm-testing.yml | 15 +++++++++++---- script/sign-hsm.bat | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deployment-hsm-testing.yml b/.github/workflows/deployment-hsm-testing.yml index d88c1472a..e9080e384 100644 --- a/.github/workflows/deployment-hsm-testing.yml +++ b/.github/workflows/deployment-hsm-testing.yml @@ -87,9 +87,16 @@ jobs: # TimestampDigest # TimestampRfc3161 } | ConvertTo-Json | Out-File -FilePath $Env:METADATA_PATH + # Azure Code Signing leverages the environment variables for secrets that complement the metadata.json + # file generated above (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID) + # + # For more information, see https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet - name: Build release binaries shell: bash env: + AZURE_CLIENT_ID: ${{ secrets.SPN_GITHUB_CLI_CLIENT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.SPN_GITHUB_CLI }} + AZURE_TENANT_ID: ${{ secrets.SPN_GITHUB_CLI_TENANT_ID }} DLIB_PATH: ${{ runner.temp }}\acs\bin\x64\Azure.CodeSigning.Dlib.dll METADATA_PATH: ${{ runner.temp }}\acs\metadata.json TAG_NAME: ${{ inputs.tag_name }} @@ -130,9 +137,9 @@ jobs: - name: Sign .msi release binaries uses: azure/azure-code-signing-action@6c86237186b7eed50c9e8a3a6e42131bcc5e4601 with: - azure-tenant-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_TENANT_ID }} - azure-client-id: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO_CLIENT_ID }} - azure-client-secret: ${{ secrets.SPN_SPN_AZURE_CODE_SIGNING_DEMO }} + azure-tenant-id: ${{ secrets.SPN_GITHUB_CLI_TENANT_ID }} + azure-client-id: ${{ secrets.SPN_GITHUB_CLI_CLIENT_ID }} + azure-client-secret: ${{ secrets.SPN_GITHUB_CLI }} endpoint: https://wus.codesigning.azure.net/ code-signing-account-name: GitHubInc certificate-profile-name: GitHubInc @@ -148,4 +155,4 @@ jobs: retention-days: 7 path: | dist/*.zip - dist/*.msi \ No newline at end of file + dist/*.msi diff --git a/script/sign-hsm.bat b/script/sign-hsm.bat index 7d0347178..2a2d7d1ee 100644 --- a/script/sign-hsm.bat +++ b/script/sign-hsm.bat @@ -11,4 +11,4 @@ if "%METADATA_PATH%" == "" ( ) REM For more information on signtool, see https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool -.\script\signtool sign /fd sha256 /td sha256 /tr http://timestamp.acs.microsoft.com /v /dlib "%DLIB_PATH%" /dmdf "%METADATA_PATH%" "%1" \ No newline at end of file +"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool" sign /fd sha256 /td sha256 /tr http://timestamp.acs.microsoft.com /v /dlib "%DLIB_PATH%" /dmdf "%METADATA_PATH%" "%1" From bcbd848bfe656f711b39d3a2e602f277c1c07fac Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Tue, 12 Dec 2023 09:54:55 -0500 Subject: [PATCH 7/9] Remove unnecessary copying, fix secrets part deux --- .github/workflows/deployment-hsm-testing.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deployment-hsm-testing.yml b/.github/workflows/deployment-hsm-testing.yml index e9080e384..62d887926 100644 --- a/.github/workflows/deployment-hsm-testing.yml +++ b/.github/workflows/deployment-hsm-testing.yml @@ -45,9 +45,6 @@ jobs: Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Azure.CodeSigning.Client/1.0.38 -OutFile $Env:ACS_ZIP -Verbose Expand-Archive $acsZip -Destination $Env:ACS_DIR acsDir -Force -Verbose - # Replace ancient signtool in scripts with one that supports ACS - Copy-Item -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\*" -Include signtool.exe,signtool.exe.manifest,Microsoft.Windows.Build.Signing.mssign32.dll.manifest,mssign32.dll,Microsoft.Windows.Build.Signing.wintrust.dll.manifest,wintrust.dll,Microsoft.Windows.Build.Appx.AppxSip.dll.manifest,AppxSip.dll,Microsoft.Windows.Build.Appx.AppxPackaging.dll.manifest,AppxPackaging.dll,Microsoft.Windows.Build.Appx.OpcServices.dll.manifest,OpcServices.dll -Destination scripts -Verbose - # Generate metadata file for signtool @{ CertificateProfileName = "GitHubInc" @@ -94,9 +91,9 @@ jobs: - name: Build release binaries shell: bash env: - AZURE_CLIENT_ID: ${{ secrets.SPN_GITHUB_CLI_CLIENT_ID }} - AZURE_CLIENT_SECRET: ${{ secrets.SPN_GITHUB_CLI }} - AZURE_TENANT_ID: ${{ secrets.SPN_GITHUB_CLI_TENANT_ID }} + AZURE_CLIENT_ID: ${{ secrets.SPN_GITHUB_CLI_SIGNING_CLIENT_ID }} + AZURE_CLIENT_SECRET: ${{ secrets.SPN_GITHUB_CLI_SIGNING }} + AZURE_TENANT_ID: ${{ secrets.SPN_GITHUB_CLI_SIGNING_TENANT_ID }} DLIB_PATH: ${{ runner.temp }}\acs\bin\x64\Azure.CodeSigning.Dlib.dll METADATA_PATH: ${{ runner.temp }}\acs\metadata.json TAG_NAME: ${{ inputs.tag_name }} @@ -137,9 +134,9 @@ jobs: - name: Sign .msi release binaries uses: azure/azure-code-signing-action@6c86237186b7eed50c9e8a3a6e42131bcc5e4601 with: - azure-tenant-id: ${{ secrets.SPN_GITHUB_CLI_TENANT_ID }} - azure-client-id: ${{ secrets.SPN_GITHUB_CLI_CLIENT_ID }} - azure-client-secret: ${{ secrets.SPN_GITHUB_CLI }} + azure-tenant-id: ${{ secrets.SPN_GITHUB_CLI_SIGNING_TENANT_ID }} + azure-client-id: ${{ secrets.SPN_GITHUB_CLI_SIGNING_CLIENT_ID }} + azure-client-secret: ${{ secrets.SPN_GITHUB_CLI_SIGNING }} endpoint: https://wus.codesigning.azure.net/ code-signing-account-name: GitHubInc certificate-profile-name: GitHubInc From 783dbf999af7e8a0617ea2c49e15d704a288e83a Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Tue, 12 Dec 2023 09:56:35 -0500 Subject: [PATCH 8/9] Remove fugue artifact --- .github/workflows/deployment-hsm-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployment-hsm-testing.yml b/.github/workflows/deployment-hsm-testing.yml index 62d887926..71eb7778f 100644 --- a/.github/workflows/deployment-hsm-testing.yml +++ b/.github/workflows/deployment-hsm-testing.yml @@ -43,7 +43,7 @@ jobs: METADATA_PATH: ${{ runner.temp }}\acs\metadata.json run: | Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Azure.CodeSigning.Client/1.0.38 -OutFile $Env:ACS_ZIP -Verbose - Expand-Archive $acsZip -Destination $Env:ACS_DIR acsDir -Force -Verbose + Expand-Archive $acsZip -Destination $Env:ACS_DIR -Force -Verbose # Generate metadata file for signtool @{ From 35f99ee426384831799997fac22909e5fdab3dea Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Tue, 12 Dec 2023 10:09:47 -0500 Subject: [PATCH 9/9] Final fixes --- .github/workflows/deployment-hsm-testing.yml | 38 ++------------------ script/sign-hsm.bat | 2 +- 2 files changed, 4 insertions(+), 36 deletions(-) diff --git a/.github/workflows/deployment-hsm-testing.yml b/.github/workflows/deployment-hsm-testing.yml index 71eb7778f..2d586a79c 100644 --- a/.github/workflows/deployment-hsm-testing.yml +++ b/.github/workflows/deployment-hsm-testing.yml @@ -43,50 +43,18 @@ jobs: METADATA_PATH: ${{ runner.temp }}\acs\metadata.json run: | Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Azure.CodeSigning.Client/1.0.38 -OutFile $Env:ACS_ZIP -Verbose - Expand-Archive $acsZip -Destination $Env:ACS_DIR -Force -Verbose + Expand-Archive $Env:ACS_ZIP -Destination $Env:ACS_DIR -Force -Verbose # Generate metadata file for signtool @{ CertificateProfileName = "GitHubInc" CodeSigningAccountName = "GitHubInc" CorrelationId = $Env:CORRELATION_ID - Description = "GitHub CLI" - Endpoint = "https://wus.codesigning.azure.net/ - - # Unused metadata configuration: - # AppendSignature - # DescriptionUrl - # EnhancedKeyUsage - # ExcludeAzureCliCredential - # ExcludeAzurePowerShellCredential - # ExcludeEnvironmentCredential - # ExcludeInteractiveBrowserCredential - # ExcludeManagedIdentityCredential - # ExcludeSharedTokenCacheCredential - # ExcludeVisualStudioCodeCredential - # ExcludeVisualStudioCredential - # FileDigest - # FilesCatalog - # FilesFolder - # FilesFolderDepth - # FilesFolderFilter - # FilesFolderRecurse - # GenerateDigestPath - # GenerateDigestXml - # GeneratePageHashes - # GeneratePkcs7 - # IngestDigestPath - # Pkcs7Oid - # Pkcs7Options - # SignDigest - # SuppressPageHashes - # Timeout - # TimestampDigest - # TimestampRfc3161 + Endpoint = "https://wus.codesigning.azure.net/" } | ConvertTo-Json | Out-File -FilePath $Env:METADATA_PATH + # Azure Code Signing leverages the environment variables for secrets that complement the metadata.json # file generated above (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID) - # # For more information, see https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet - name: Build release binaries shell: bash diff --git a/script/sign-hsm.bat b/script/sign-hsm.bat index 2a2d7d1ee..2b70726f7 100644 --- a/script/sign-hsm.bat +++ b/script/sign-hsm.bat @@ -11,4 +11,4 @@ if "%METADATA_PATH%" == "" ( ) REM For more information on signtool, see https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool -"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool" sign /fd sha256 /td sha256 /tr http://timestamp.acs.microsoft.com /v /dlib "%DLIB_PATH%" /dmdf "%METADATA_PATH%" "%1" +"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool" sign /d "GitHub CLI" /fd sha256 /td sha256 /tr http://timestamp.acs.microsoft.com /v /dlib "%DLIB_PATH%" /dmdf "%METADATA_PATH%" "%1"