Skip to content

Merge pull request #604 from mountaindude/587 #35

Merge pull request #604 from mountaindude/587

Merge pull request #604 from mountaindude/587 #35

name: insiders-build
on:
workflow_dispatch:
push:
branches:
- main
jobs:
insiders-build:
strategy:
matrix:
os: [win-code-sign, mac-build1, ubuntu-latest]
include:
- os: win-code-sign
build: |
cd src
./node_modules/.bin/esbuild "${env:DIST_FILE_NAME}.js" --bundle --outfile=build.cjs --format=cjs --platform=node --target=node23
node --experimental-sea-config sea-config.json
node -e "require('fs').copyFileSync(process.execPath, '${env:DIST_FILE_NAME}.exe')"
pwd
dir
# -------------------
# Remove the signature from the executable
$processOptions1 = @{
FilePath = "C:\Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/signtool.exe"
Wait = $true
ArgumentList = "remove", "/s", "./${env:DIST_FILE_NAME}.exe"
WorkingDirectory = "."
NoNewWindow = $true
}
Start-Process @processOptions1
npx postject "${env:DIST_FILE_NAME}.exe" NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
# -------------------
# Sign the executable
# 1st signing
$processOptions1 = @{
FilePath = "C:\Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/signtool.exe"
Wait = $true
ArgumentList = "sign", "/sha1", "$env:CODESIGN_WIN_THUMBPRINT", "/tr", "http://time.certum.pl", "/td", "sha256", "/fd", "sha1", "/v", "./${env:DIST_FILE_NAME}.exe"
WorkingDirectory = "."
NoNewWindow = $true
}
Start-Process @processOptions1
# -------------------
# 2nd signing
$processOptions2 = @{
FilePath = "C:\Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/signtool.exe"
Wait = $true
ArgumentList = "sign", "/sha1", "$env:CODESIGN_WIN_THUMBPRINT", "/tr", "http://time.certum.pl", "/td", "sha256", "/fd", "sha256", "/v", "./${env:DIST_FILE_NAME}.exe"
WorkingDirectory = "."
NoNewWindow = $true
}
Start-Process @processOptions2
# -------------------
# Create insider's build zip
$compress = @{
Path = "./${env:DIST_FILE_NAME}.exe"
CompressionLevel = "Fastest"
DestinationPath = "${env:DIST_FILE_NAME}--win-x64--${{ github.sha }}.zip"
}
Compress-Archive @compress
# -------------------
# Move the zip file to the root directory
Move-Item "${env:DIST_FILE_NAME}--win-x64--${{ github.sha }}.zip" ..
# -------------------
# Clean up
Remove-Item -Force build.cjs
dir
artifact_insider: butler-sheet-icons--win-x64--${{ github.sha }}.zip
- os: mac-build1
build: |
cd src
./node_modules/.bin/esbuild ${DIST_FILE_NAME}.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node23
node --experimental-sea-config sea-config.json
cp $(command -v node) ${DIST_FILE_NAME}
npx postject ${DIST_FILE_NAME} NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 --macho-segment-name NODE_SEA
security delete-keychain build.keychain || true
pwd
ls -la
# -------------------
# Turn our base64-encoded certificate back to a regular .p12 file
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
# -------------------
# We need to create a new keychain, otherwise using the certificate will prompt
# with a UI dialog asking for the certificate password, which we can't
# use in a headless CI environment
security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security list-keychains -d user -s build.keychain
security default-keychain -d user -s build.keychain
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
codesign --force -s "$MACOS_CERTIFICATE_NAME" -v "./${DIST_FILE_NAME}" --deep --strict --options=runtime --timestamp --entitlements ../release-config/${DIST_FILE_NAME}.entitlements
# -------------------
# Notarize
# Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
# -------------------
# We can't notarize an app bundle directly, but we need to compress it as an archive.
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
# notarization service
# Notarize insider binary
echo "Creating temp notarization archive for insider build"
ditto -c -k --keepParent "./${DIST_FILE_NAME}" "./${DIST_FILE_NAME}--macos-x64--${{ github.sha }}.zip"
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
# characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
# you're curious
echo "Notarize insider app"
xcrun notarytool submit "./${DIST_FILE_NAME}--macos-x64--${{ github.sha }}.zip" --keychain-profile "notarytool-profile" --wait
# -------------------
# Move the zip file to the root directory
mv "./${DIST_FILE_NAME}--macos-x64--${{ github.sha }}.zip" ..
# -------------------
# Clean up
# Delete build keychain
security delete-keychain build.keychain
rm build.cjs
ls -la
artifact_insider: butler-sheet-icons--macos-x64--${{ github.sha }}.zip
- os: ubuntu-latest
build: |
cd src
./node_modules/.bin/esbuild ${DIST_FILE_NAME}.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node23
node --experimental-sea-config sea-config.json
cp $(command -v node) ${DIST_FILE_NAME}
npx postject ${DIST_FILE_NAME} NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
# Compress insider's build
tar -czf "${DIST_FILE_NAME}--linux-x64--${{ github.sha }}.tgz" "${DIST_FILE_NAME}"
ls -la
# -------------------
# Move the zip file to the root directory
mv "${DIST_FILE_NAME}--linux-x64--${{ github.sha }}.tgz" ..
# -------------------
# Clean up
rm build.cjs
ls -la
artifact_insider: butler-sheet-icons--linux-x64--${{ github.sha }}.tgz
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 23
- name: Install tool for creating stand-alone executables
run: |
npm install pkg --location=global
- name: Install dependencies
run: |
pwd
cd src
npm ci --include=prod
- name: Run Snyk to check for vulnerabilities
if: |
github.repository_owner == 'ptarmiganlabs' &&
matrix.os == 'ubuntu-latest'
uses: snyk/actions/node@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --file=./src/package.json --sarif-file-output=snyk.sarif
- name: Upload Snyk result to GitHub Code Scanning
continue-on-error: true
if: |
github.repository_owner == 'ptarmiganlabs' &&
matrix.os == 'ubuntu-latest'
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: snyk.sarif
- name: Create binaries
env:
DIST_FILE_NAME: butler-sheet-icons
GITHUB_TOKEN: ${{ secrets.PAT }}
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE_BASE64_CODESIGN }}
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_CODESIGN_PWD }}
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_CODESIGN_NAME }}
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
CODESIGN_WIN_THUMBPRINT: ${{ secrets.WIN_CODESIGN_THUMBPRINT}}
run: |
pwd
${{ matrix.build }}
- name: Upload insider build artifacts to GitHub
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_insider }}
path: ${{ matrix.artifact_insider }}