Files
libhalo/.github/workflows/prod_build_cli.yml
2023-03-18 14:09:18 +01:00

263 lines
11 KiB
YAML

name: Release halocli tool
on:
push:
tags:
- 'halocli-v*'
jobs:
create_release:
name: Create halocli release
runs-on: ubuntu-latest
steps:
- name: Prepare version number
id: parse_version
run: |
( echo -n "version=" && ( echo "$GITHUB_REF" | cut -f2 -d- | tr -d '\n' ) ) >> "$GITHUB_OUTPUT"
- name: Draft release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: HaLo CLI ${{ steps.parse_version.outputs.version }}
draft: true
prerelease: false
body: |
Standalone command line tool for desktop computers with PC/SC readers (USB/NFC readers).
Release contents:
* `halocli-linux-x64.tgz` - Linux x64 build (elf; tar-gzip compressed)
* `halocli-win-x64.exe` - Windows 64 build (exe; signed; zipped)
* `halocli-macos-x64.pkg` - Mac OS x64 build (installer; signed)
**Note:** The files `*-keyless.sig` and `*-keyless.pem` constitute a part of [build audit trail](https://github.com/arx-research/libhalo/blob/master/docs/build-audit-trail.md).
- name: Store release upload URL
run: |
echo -n "${{ steps.create_release.outputs.upload_url }}" > release-upload-url.txt
- name: Store release upload URL artifact
uses: actions/upload-artifact@v3
with:
name: release-upload-url
path: release-upload-url.txt
build_cli_tool:
permissions:
id-token: write
strategy:
matrix:
include:
- os: ubuntu-latest
bin_name: halocli
- os: windows-latest
bin_name: halocli.exe
- os: macos-latest
bin_name: halocli
name: Build halocli (${{ matrix.os }})
runs-on: ${{ matrix.os }}
needs: create_release
steps:
- name: Install native dependencies (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update && sudo apt-get install -y libpcsclite-dev
- name: Install native dependencies (MacOS)
if: matrix.os == 'macos-latest'
run: |
brew install pcsc-lite
- name: Checkout the repository
uses: actions/checkout@v3
- name: Install Node.JS
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies (root)
run: |
npm --include=dev ci
- name: Install dependencies (cli)
run: |
cd cli
npm --include=dev ci
- name: Package HaLo CLI tool (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
cd cli
node_modules/.bin/pkg -t node16-linux-x64 package.json
- name: Package HaLo CLI tool (Windows)
if: matrix.os == 'windows-latest'
run: |
cd cli
node_modules/.bin/pkg -t node16-win-x64 package.json
- name: Package HaLo CLI tool (MacOS)
if: matrix.os == 'macos-latest'
run: |
cd cli
node_modules/.bin/pkg -t node16-macos-x64 package.json
- name: Store Entitlements.plist in dist
if: matrix.os == 'macos-latest'
run:
mv ./cli/Entitlements.plist ./cli/dist/Entitlements.plist
- name: Install cosign
uses: sigstore/cosign-installer@c3667d99424e7e6047999fb6246c0da843953c65
- name: Sign binary with cosign
run: |
echo y | cosign sign-blob ./cli/dist/${{ matrix.bin_name }} --output-certificate ./cli/dist/${{ matrix.bin_name }}.pem --output-signature ./cli/dist/${{ matrix.bin_name }}.sig
- name: Store binary as artifact
uses: actions/upload-artifact@v3
with:
name: binary-${{ matrix.os }}
path: ./cli/dist/
sign_cli_tool:
environment: production
permissions:
contents: write
id-token: write
strategy:
matrix:
include:
- os: ubuntu-latest
bin_name: halocli
out_name: halocli-linux-x64.tgz
- os: windows-latest
bin_name: halocli.exe
out_name: halocli-win-x64.zip
- os: macos-latest
bin_name: halocli
out_name: halocli-macos-x64.pkg
name: Sign halocli and release (${{ matrix.os }})
runs-on: ${{ matrix.os }}
needs: build_cli_tool
steps:
- name: Install cosign
uses: sigstore/cosign-installer@c3667d99424e7e6047999fb6246c0da843953c65
- name: Download binary from artifact
uses: actions/download-artifact@v3
with:
name: binary-${{ matrix.os }}
- name: Verify signatures from previous stage
shell: bash
run: |
cosign verify-blob --cert ./${{ matrix.bin_name }}.pem --signature ./${{ matrix.bin_name }}.sig --certificate-identity "https://github.com/arx-research/libhalo/.github/workflows/prod_build_cli.yml@${GITHUB_REF}" --certificate-oidc-issuer https://token.actions.githubusercontent.com ./${{ matrix.bin_name }}
rm ./${{ matrix.bin_name }}.pem
rm ./${{ matrix.bin_name }}.sig
- name: Calculate checksum of Entitlements.plist (Mac OS)
if: matrix.os == 'macos-latest'
run: |
shasum -a 256 Entitlements.plist
- name: Verify Entitlements.plist (Mac OS)
if: matrix.os == 'macos-latest'
run: |
echo "bb1c65f6915e18f6e371a76e0b84551756a0e5037e90ef541680c95831fb52a7 Entitlements.plist" > Entitlements.plist.sum
shasum -a 256 -c Entitlements.plist.sum
- name: Compress application (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
chmod +x halocli
tar -pczf halocli-linux-x64.tgz halocli
- name: Write certificate file (Windows)
if: matrix.os == 'windows-latest'
uses: DamianReeves/write-file-action@0a7fcbe1960c53fc08fe789fa4850d24885f4d84
with:
path: ./chain.cer
write-mode: overwrite
contents: ${{ vars.WINDOWS_CODE_SIGN_CERT_CHAIN }}
- name: Download jsign and verify (Windows)
if: matrix.os == 'windows-latest'
shell: bash
run: |
curl -s -L -o jsign.jar https://github.com/ebourg/jsign/releases/download/4.2/jsign-4.2.jar
echo "290377fc4f593256200b3ea4061b7409e8276255f449d4c6de7833faf0850cc1 jsign.jar" > jsign.sum
sha256sum -c jsign.sum
- name: Authenticate with gcloud (Windows)
if: matrix.os == 'windows-latest'
uses: google-github-actions/auth@ef5d53e30bbcd8d0836f4288f5e50ff3e086997d
with:
credentials_json: ${{ secrets.GCLOUD_SERVICE_ACCOUNT_KEY }}
- name: Set up Cloud SDK (Windows)
uses: google-github-actions/setup-gcloud@62d4898025f6041e16b1068643bfc5a696863587
if: matrix.os == 'windows-latest'
with:
install_components: 'gcloud'
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
- name: Sign application (Windows)
if: matrix.os == 'windows-latest'
shell: bash
run: |
java -jar jsign.jar --storetype GOOGLECLOUD --storepass "$(gcloud auth print-access-token)" --keystore "${{ vars.WINDOWS_CODE_SIGN_KEYSTORE }}" --alias "${{ vars.WINDOWS_CODE_SIGN_KEY_ALIAS }}" --certfile "chain.cer" --tsmode RFC3161 --tsaurl http://timestamp.globalsign.com/tsa/r6advanced1 halocli.exe
- name: Compress application (Windows)
if: matrix.os == 'windows-latest'
run: |
Compress-Archive halocli.exe halocli-win-x64.zip
- name: Load signing credentials (Mac OS)
if: matrix.os == 'macos-latest'
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
with:
p12-file-base64: ${{ secrets.MACOS_SIGN_P12 }}
p12-password: ${{ secrets.MACOS_SIGN_P12_PASSWORD }}
- name: Sign application (Mac OS)
if: matrix.os == 'macos-latest'
run: |
mkdir -p root/usr/local/bin/
mv halocli root/usr/local/bin/halocli
/usr/bin/codesign --deep --force --options=runtime --entitlements ./Entitlements.plist --sign "${{ secrets.MACOS_SIGN_IDENTITY_APPLICATION }}" --timestamp ./root/usr/local/bin/halocli
chmod +x ./root/usr/local/bin/halocli
pkgbuild --root ./root --identifier "org.arx.halo.halocli" --version "1.0.$(date +%s)" --install-location "/" --sign "${{ secrets.MACOS_SIGN_IDENTITY_INSTALLER }}" ./halocli-macos-x64.pkg
- name: Notarize application for Mac OS
if: matrix.os == 'macos-latest'
run: |
xcrun notarytool submit "--apple-id=${{ secrets.MACOS_NOTARIZE_APPLE_ID }}" "--password=${{ secrets.MACOS_NOTARIZE_PASSWORD }}" "--team-id=${{ secrets.MACOS_NOTARIZE_TEAM_ID }}" --progress --wait ./halocli-macos-x64.pkg
- name: Staple notarized application (Mac OS)
if: matrix.os == 'macos-latest'
run: |
xcrun stapler staple ./halocli-macos-x64.pkg
rm -rf ./root/
- name: Download release upload URL
uses: actions/download-artifact@v3
with:
name: release-upload-url
- name: Store release upload URL output
id: out_store
shell: bash
run: |
echo "release_upload_url=$(cat release-upload-url.txt)" >> "$GITHUB_OUTPUT"
- name: Sign output binaries with cosign
run: |
echo y | cosign sign-blob ./${{ matrix.out_name }} --output-certificate ./${{ matrix.out_name }}-keyless.pem --output-signature ./${{ matrix.out_name }}-keyless.sig
- name: Upload release asset (binary)
id: upload-release-asset-binary
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.out_store.outputs.release_upload_url }}
asset_path: ./${{ matrix.out_name }}
asset_name: ${{ matrix.out_name }}
asset_content_type: application/octet-stream
- name: Upload release asset (cosign pem)
id: upload-release-asset-cosign-pem
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.out_store.outputs.release_upload_url }}
asset_path: ./${{ matrix.out_name }}-keyless.pem
asset_name: ${{ matrix.out_name }}-keyless.pem
asset_content_type: application/octet-stream
- name: Upload release asset (cosign sig)
id: upload-release-asset-cosign-sig
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.out_store.outputs.release_upload_url }}
asset_path: ./${{ matrix.out_name }}-keyless.sig
asset_name: ${{ matrix.out_name }}-keyless.sig
asset_content_type: application/octet-stream
- name: Delete binary artifact
if: always()
uses: geekyeggo/delete-artifact@54ab544f12cdb7b71613a16a2b5a37a9ade990af
with:
name: binary-${{ matrix.os }}