344 lines
12 KiB
YAML
344 lines
12 KiB
YAML
name: Deployment
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref_name }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag_name:
|
|
required: true
|
|
type: string
|
|
environment:
|
|
default: production
|
|
type: environment
|
|
go_version:
|
|
default: "1.19"
|
|
type: string
|
|
platforms:
|
|
default: "linux,macos,windows"
|
|
type: string
|
|
release:
|
|
description: "Whether to create a GitHub Release"
|
|
type: boolean
|
|
default: true
|
|
|
|
jobs:
|
|
linux:
|
|
runs-on: ubuntu-latest
|
|
environment: ${{ inputs.environment }}
|
|
if: contains(inputs.platforms, 'linux')
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v3
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v4
|
|
with:
|
|
go-version: ${{ inputs.go_version }}
|
|
- name: Install GoReleaser
|
|
uses: goreleaser/goreleaser-action@v4
|
|
with:
|
|
version: "~1.17.1"
|
|
install-only: true
|
|
- name: Build release binaries
|
|
env:
|
|
TAG_NAME: ${{ inputs.tag_name }}
|
|
run: script/release --local "$TAG_NAME" --platform linux
|
|
- name: Generate web manual pages
|
|
run: |
|
|
go run ./cmd/gen-docs --website --doc-path dist/manual
|
|
tar -czvf dist/manual.tar.gz -C dist -- manual
|
|
- uses: actions/upload-artifact@v3
|
|
with:
|
|
name: linux
|
|
if-no-files-found: error
|
|
retention-days: 7
|
|
path: |
|
|
dist/*.tar.gz
|
|
dist/*.rpm
|
|
dist/*.deb
|
|
|
|
macos:
|
|
runs-on: macos-latest
|
|
environment: ${{ inputs.environment }}
|
|
if: contains(inputs.platforms, 'macos')
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v3
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v4
|
|
with:
|
|
go-version: ${{ inputs.go_version }}
|
|
- name: Configure macOS signing
|
|
if: inputs.environment == 'production'
|
|
env:
|
|
APPLE_DEVELOPER_ID: ${{ vars.APPLE_DEVELOPER_ID }}
|
|
APPLE_APPLICATION_CERT: ${{ secrets.APPLE_APPLICATION_CERT }}
|
|
APPLE_APPLICATION_CERT_PASSWORD: ${{ secrets.APPLE_APPLICATION_CERT_PASSWORD }}
|
|
run: |
|
|
keychain="$RUNNER_TEMP/buildagent.keychain"
|
|
keychain_password="password1"
|
|
|
|
security create-keychain -p "$keychain_password" "$keychain"
|
|
security default-keychain -s "$keychain"
|
|
security unlock-keychain -p "$keychain_password" "$keychain"
|
|
|
|
base64 -D <<<"$APPLE_APPLICATION_CERT" > "$RUNNER_TEMP/cert.p12"
|
|
security import "$RUNNER_TEMP/cert.p12" -k "$keychain" -P "$APPLE_APPLICATION_CERT_PASSWORD" -T /usr/bin/codesign
|
|
security set-key-partition-list -S "apple-tool:,apple:,codesign:" -s -k "$keychain_password" "$keychain"
|
|
rm "$RUNNER_TEMP/cert.p12"
|
|
- name: Install GoReleaser
|
|
uses: goreleaser/goreleaser-action@v4
|
|
with:
|
|
version: "~1.17.1"
|
|
install-only: true
|
|
- name: Build release binaries
|
|
env:
|
|
TAG_NAME: ${{ inputs.tag_name }}
|
|
APPLE_DEVELOPER_ID: ${{ vars.APPLE_DEVELOPER_ID }}
|
|
run: script/release --local "$TAG_NAME" --platform macos
|
|
- name: Notarize macOS archives
|
|
if: inputs.environment == 'production'
|
|
env:
|
|
APPLE_ID: ${{ vars.APPLE_ID }}
|
|
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
|
APPLE_DEVELOPER_ID: ${{ vars.APPLE_DEVELOPER_ID }}
|
|
run: |
|
|
shopt -s failglob
|
|
script/sign dist/gh_*_macOS_*.zip
|
|
- uses: actions/upload-artifact@v3
|
|
with:
|
|
name: macos
|
|
if-no-files-found: error
|
|
retention-days: 7
|
|
path: |
|
|
dist/*.tar.gz
|
|
dist/*.zip
|
|
|
|
windows:
|
|
runs-on: windows-latest
|
|
environment: ${{ inputs.environment }}
|
|
if: contains(inputs.platforms, 'windows')
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v3
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v4
|
|
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@v4
|
|
with:
|
|
version: "~1.17.1"
|
|
install-only: true
|
|
- name: Build release binaries
|
|
shell: bash
|
|
env:
|
|
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
|
|
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
|
|
if: inputs.environment == 'production'
|
|
shell: pwsh
|
|
run: |
|
|
Get-ChildItem -Path .\dist -Filter *.msi | ForEach-Object {
|
|
.\script\sign $_.FullName
|
|
}
|
|
env:
|
|
CERT_FILE: ${{ steps.obtain_cert.outputs.cert-file }}
|
|
CERT_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }}
|
|
- uses: actions/upload-artifact@v3
|
|
with:
|
|
name: windows
|
|
if-no-files-found: error
|
|
retention-days: 7
|
|
path: |
|
|
dist/*.zip
|
|
dist/*.msi
|
|
|
|
release:
|
|
runs-on: ubuntu-latest
|
|
needs: [linux, macos, windows]
|
|
if: inputs.release
|
|
steps:
|
|
- name: Checkout cli/cli
|
|
uses: actions/checkout@v3
|
|
- name: Merge built artifacts
|
|
uses: actions/download-artifact@v3
|
|
- name: Checkout documentation site
|
|
uses: actions/checkout@v3
|
|
with:
|
|
repository: github/cli.github.com
|
|
path: site
|
|
fetch-depth: 0
|
|
ssh-key: ${{ secrets.SITE_SSH_KEY }}
|
|
- name: Update site man pages
|
|
env:
|
|
GIT_COMMITTER_NAME: cli automation
|
|
GIT_AUTHOR_NAME: cli automation
|
|
GIT_COMMITTER_EMAIL: noreply@github.com
|
|
GIT_AUTHOR_EMAIL: noreply@github.com
|
|
TAG_NAME: ${{ inputs.tag_name }}
|
|
run: |
|
|
git -C site rm 'manual/gh*.md' 2>/dev/null || true
|
|
tar -xzvf linux/manual.tar.gz -C site
|
|
git -C site add 'manual/gh*.md'
|
|
sed -i.bak -E "s/(assign version = )\".+\"/\1\"${TAG_NAME#v}\"/" site/index.html
|
|
rm -f site/index.html.bak
|
|
git -C site add index.html
|
|
git -C site diff --quiet --cached || git -C site commit -m "gh ${TAG_NAME#v}"
|
|
- name: Prepare release assets
|
|
env:
|
|
TAG_NAME: ${{ inputs.tag_name }}
|
|
run: |
|
|
shopt -s failglob
|
|
rm -rf dist
|
|
mkdir dist
|
|
mv -v {linux,macos,windows}/gh_* dist/
|
|
- name: Install packaging dependencies
|
|
run: sudo apt-get install -y rpm reprepro
|
|
- name: Set up GPG
|
|
if: inputs.environment == 'production'
|
|
env:
|
|
GPG_PUBKEY: ${{ secrets.GPG_PUBKEY }}
|
|
GPG_KEY: ${{ secrets.GPG_KEY }}
|
|
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
GPG_KEYGRIP: ${{ secrets.GPG_KEYGRIP }}
|
|
run: |
|
|
base64 -d <<<"$GPG_PUBKEY" | gpg --import --no-tty --batch --yes
|
|
base64 -d <<<"$GPG_KEY" | gpg --import --no-tty --batch --yes
|
|
echo "allow-preset-passphrase" > ~/.gnupg/gpg-agent.conf
|
|
gpg-connect-agent RELOADAGENT /bye
|
|
/usr/lib/gnupg2/gpg-preset-passphrase --preset "$GPG_KEYGRIP" <<<"$GPG_PASSPHRASE"
|
|
- name: Sign RPMs
|
|
if: inputs.environment == 'production'
|
|
run: |
|
|
cp script/rpmmacros ~/.rpmmacros
|
|
rpmsign --addsign dist/*.rpm
|
|
- name: Run createrepo
|
|
env:
|
|
GPG_SIGN: ${{ inputs.environment == 'production' }}
|
|
run: |
|
|
mkdir -p site/packages/rpm
|
|
cp dist/*.rpm site/packages/rpm/
|
|
./script/createrepo.sh
|
|
cp -r dist/repodata site/packages/rpm/
|
|
pushd site/packages/rpm
|
|
[ "$GPG_SIGN" = "false" ] || gpg --yes --detach-sign --armor repodata/repomd.xml
|
|
popd
|
|
- name: Run reprepro
|
|
env:
|
|
GPG_SIGN: ${{ inputs.environment == 'production' }}
|
|
# We are no longer adding to the distribution list.
|
|
# All apt distributions should use "stable" according to our install documentation.
|
|
# In the future we will remove legacy distributions listed here.
|
|
RELEASES: "cosmic eoan disco groovy focal stable oldstable testing sid unstable buster bullseye stretch jessie bionic trusty precise xenial hirsute impish kali-rolling"
|
|
run: |
|
|
mkdir -p upload
|
|
[ "$GPG_SIGN" = "true" ] || sed -i.bak '/^SignWith:/d' script/distributions
|
|
for release in $RELEASES; do
|
|
for file in dist/*.deb; do
|
|
reprepro --confdir="+b/script" includedeb "$release" "$file"
|
|
done
|
|
done
|
|
cp -a dists/ pool/ upload/
|
|
mkdir -p site/packages
|
|
cp -a upload/* site/packages/
|
|
- name: Create the release
|
|
env:
|
|
DO_PUBLISH: ${{ inputs.environment == 'production' }}
|
|
TAG_NAME: ${{ inputs.tag_name }}
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
shopt -s failglob
|
|
pushd dist
|
|
shasum -a 256 gh_* > checksums.txt
|
|
mv checksums.txt gh_${TAG_NAME#v}_checksums.txt
|
|
popd
|
|
release_args=(
|
|
"$TAG_NAME"
|
|
--title "GitHub CLI ${TAG_NAME#v}"
|
|
--target "$GITHUB_SHA"
|
|
--generate-notes
|
|
)
|
|
if [[ $TAG_NAME == *-* ]]; then
|
|
release_args+=( --prerelease )
|
|
else
|
|
release_args+=( --discussion-category "General" )
|
|
fi
|
|
action="echo"
|
|
[ "$DO_PUBLISH" = "false" ] || action="command"
|
|
script/label-assets dist/gh_* | xargs $action gh release create "${release_args[@]}" --
|
|
- name: Publish site
|
|
env:
|
|
DO_PUBLISH: ${{ inputs.environment == 'production' && !contains(inputs.tag_name, '-') }}
|
|
TAG_NAME: ${{ inputs.tag_name }}
|
|
GIT_COMMITTER_NAME: cli automation
|
|
GIT_AUTHOR_NAME: cli automation
|
|
GIT_COMMITTER_EMAIL: noreply@github.com
|
|
GIT_AUTHOR_EMAIL: noreply@github.com
|
|
working-directory: ./site
|
|
run: |
|
|
git add packages
|
|
git commit -m "Add rpm and deb packages for $TAG_NAME"
|
|
if [ "$DO_PUBLISH" = "true" ]; then
|
|
git push
|
|
else
|
|
git log --oneline @{upstream}..
|
|
git diff --name-status @{upstream}..
|
|
fi
|
|
- name: Bump homebrew-core formula
|
|
uses: mislav/bump-homebrew-formula-action@v2
|
|
if: inputs.environment == 'production' && !contains(inputs.tag_name, '-')
|
|
with:
|
|
formula-name: gh
|
|
tag-name: ${{ inputs.tag_name }}
|
|
env:
|
|
COMMITTER_TOKEN: ${{ secrets.UPLOAD_GITHUB_TOKEN }}
|