diff --git a/.github/workflows/deployment-hsm-testing.yml b/.github/workflows/deployment-hsm-testing.yml deleted file mode 100644 index c3e8f24e4..000000000 --- a/.github/workflows/deployment-hsm-testing.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: Deployment 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: 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: | - # Download Azure Code Signing client containing the DLL needed for signtool in script/sign - Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Azure.CodeSigning.Client/1.0.38 -OutFile $Env:ACS_ZIP -Verbose - Expand-Archive $Env:ACS_ZIP -Destination $Env:ACS_DIR -Force -Verbose - - # Generate metadata file for signtool, used in signing box .exe and .msi - @{ - CertificateProfileName = "GitHubInc" - CodeSigningAccountName = "GitHubInc" - CorrelationId = $Env:CORRELATION_ID - 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 - env: - 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 }} - 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 - shell: pwsh - env: - 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 - run: | - Get-ChildItem "$Env:GITHUB_WORKSPACE/dist" -Filter *.msi | Foreach-Object { - .\script\sign.ps1 $_.FullName - } - - uses: actions/upload-artifact@v3 - with: - name: windows - if-no-files-found: error - retention-days: 7 - path: | - dist/*.zip - dist/*.msi diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 39943ce6e..f93ef50b5 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -1,4 +1,5 @@ name: Deployment +run-name: ${{ inputs.tag_name }} / go ${{ inputs.go_version }} / ${{ inputs.environment }} concurrency: group: ${{ github.workflow }}-${{ github.ref_name }} @@ -130,26 +131,43 @@ jobs: uses: actions/setup-go@v5 with: go-version: ${{ inputs.go_version }} - - name: Obtain signing certificate - id: obtain_cert - if: inputs.environment == 'production' - shell: bash - run: | - base64 -d <<<"$CERT_CONTENTS" > ./cert.pfx - printf "cert-file=%s\n" ".\\cert.pfx" >> $GITHUB_OUTPUT - env: - CERT_CONTENTS: ${{ secrets.WINDOWS_CERT_PFX }} - 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: | + # Download Azure Code Signing client containing the DLL needed for signtool in script/sign + Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Azure.CodeSigning.Client/1.0.43 -OutFile $Env:ACS_ZIP -Verbose + Expand-Archive $Env:ACS_ZIP -Destination $Env:ACS_DIR -Force -Verbose + + # Generate metadata file for signtool, used in signing box .exe and .msi + @{ + CertificateProfileName = "GitHubInc" + CodeSigningAccountName = "GitHubInc" + CorrelationId = $Env:CORRELATION_ID + 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 env: + 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 }} - CERT_FILE: ${{ steps.obtain_cert.outputs.cert-file }} - CERT_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }} run: script/release --local "$TAG_NAME" --platform windows - name: Set up MSBuild id: setupmsbuild @@ -184,12 +202,18 @@ jobs: 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 + - name: Sign .msi release binaries if: inputs.environment == 'production' shell: pwsh + env: + 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 run: | Get-ChildItem -Path .\dist -Filter *.msi | ForEach-Object { - .\script\sign $_.FullName + .\script\sign.ps1 $_.FullName } env: CERT_FILE: ${{ steps.obtain_cert.outputs.cert-file }} diff --git a/.goreleaser-hsm.yml b/.goreleaser-hsm.yml deleted file mode 100644 index e469af091..000000000 --- a/.goreleaser-hsm.yml +++ /dev/null @@ -1,98 +0,0 @@ -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] - hooks: - post: - - cmd: >- - {{ if eq .Runtime.Goos "windows" }}pwsh .\script\sign.ps1{{ else }}./script/sign{{ end }} '{{ .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"}} - -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/.goreleaser.yml b/.goreleaser.yml index f441156e3..e469af091 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -41,7 +41,7 @@ builds: hooks: post: - cmd: >- - {{ if eq .Runtime.Goos "windows" }}.\script\sign{{ else }}./script/sign{{ end }} '{{ .Path }}' + {{ if eq .Runtime.Goos "windows" }}pwsh .\script\sign.ps1{{ else }}./script/sign{{ end }} '{{ .Path }}' output: true binary: bin/gh main: ./cmd/gh diff --git a/script/release-hsm b/script/release-hsm deleted file mode 100755 index dbe51c8ac..000000000 --- a/script/release-hsm +++ /dev/null @@ -1,120 +0,0 @@ -#!/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' "$config" >.goreleaser.generated.yml - config=".goreleaser.generated.yml" - ;; - macos ) - sed '/#build:windows/,/^$/d; /#build:linux/,/^$/d' "$config" >.goreleaser.generated.yml - config=".goreleaser.generated.yml" - ;; - windows ) - sed '/#build:linux/,/^$/d; /#build:macos/,/^$/d' "$config" >.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 diff --git a/script/sign-hsm.bat b/script/sign-hsm.bat deleted file mode 100644 index 2b70726f7..000000000 --- a/script/sign-hsm.bat +++ /dev/null @@ -1,14 +0,0 @@ -@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 -"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" diff --git a/script/sign.bat b/script/sign.bat deleted file mode 100644 index 4fbe8a7af..000000000 --- a/script/sign.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off - -if "%CERT_FILE%" == "" ( - echo skipping Windows code-signing; CERT_FILE not set - exit /b -) - -.\script\signtool sign /d "GitHub CLI" /f "%CERT_FILE%" /p "%CERT_PASSWORD%" /fd sha256 /tr http://timestamp.digicert.com /v "%1" \ No newline at end of file diff --git a/script/signtool.exe b/script/signtool.exe deleted file mode 100644 index 1ecf3b3cf..000000000 Binary files a/script/signtool.exe and /dev/null differ