From 1224d36ec93007b51f74d6b547ae85fec9f4a7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6ran=20Sander?= Date: Sat, 4 Oct 2025 22:05:49 +0200 Subject: [PATCH] Linting --- .github/workflows/ci.yaml | 1348 ++++++++++++++++++------------------- 1 file changed, 674 insertions(+), 674 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f0dca18..dba4e0c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,678 +1,678 @@ name: ci on: - workflow_dispatch: - push: - branches: - - master + workflow_dispatch: + push: + branches: + - master jobs: - release-please: - runs-on: ubuntu-latest - outputs: - releases_created: ${{ steps.release.outputs.releases_created }} - release_tag_name: ${{ steps.release.outputs['tag_name'] }} - release_version: ${{ steps.release.outputs['version'] }} - release_upload_url: ${{ steps.release.outputs['upload_url'] }} + release-please: + runs-on: ubuntu-latest + outputs: + releases_created: ${{ steps.release.outputs.releases_created }} + release_tag_name: ${{ steps.release.outputs['tag_name'] }} + release_version: ${{ steps.release.outputs['version'] }} + release_upload_url: ${{ steps.release.outputs['upload_url'] }} + env: + GITHUB_REF: ${{ github.ref }} + GITHUB_TOKEN: ${{ secrets.PAT }} + DIST_FILE_NAME: butler-sos + steps: + - name: Show github.ref + run: echo "$GITHUB_REF" + + - uses: googleapis/release-please-action@v4 + id: release + if: github.repository_owner == 'ptarmiganlabs' + with: + token: ${{ secrets.RELEASE_PLEASE_PAT }} + # optional. customize path to release-please-config.json + config-file: release-please-config.json + # optional. customize path to .release-please-manifest.json + manifest-file: .release-please-manifest.json + target-branch: master + + - name: Show output from Release-Please + if: always() env: - GITHUB_REF: ${{ github.ref }} - GITHUB_TOKEN: ${{ secrets.PAT }} - DIST_FILE_NAME: butler-sos - steps: - - name: Show github.ref - run: echo "$GITHUB_REF" - - - uses: googleapis/release-please-action@v4 - id: release - if: github.repository_owner == 'ptarmiganlabs' - with: - token: ${{ secrets.RELEASE_PLEASE_PAT }} - # optional. customize path to release-please-config.json - config-file: release-please-config.json - # optional. customize path to .release-please-manifest.json - manifest-file: .release-please-manifest.json - target-branch: master - - - name: Show output from Release-Please - if: always() - env: - RELEASE_PLEASE_OUTPUT: ${{ toJSON(steps.release.outputs) }} - run: echo "$RELEASE_PLEASE_OUTPUT" - - - name: Show output from Release-Please - run: | - echo "releases_created: ${{ steps.release.outputs.releases_created }}" - echo "release_created : ${{ steps.release.outputs.release_created }}" - echo "draft : ${{ steps.release.outputs['draft'] }}" - echo "path : ${{ steps.release.outputs['path'] }}" - echo "upload_url : ${{ steps.release.outputs['upload_url'] }}" - echo "html_url : ${{ steps.release.outputs['html_url'] }}" - echo "tag_name : ${{ steps.release.outputs['tag_name'] }}" - echo "version : ${{ steps.release.outputs['version'] }}" - echo "major : ${{ steps.release.outputs['major'] }}" - echo "minor : ${{ steps.release.outputs['minor'] }}" - echo "patch : ${{ steps.release.outputs['patch'] }}" - echo "sha : ${{ steps.release.outputs['sha'] }}" - - sbom-build: - needs: release-please - runs-on: ubuntu-latest - - if: needs.release-please.outputs.releases_created == 'true' - env: - DIST_FILE_NAME: butler-sos - - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Setup Node.js - uses: actions/setup-node@v5 - with: - node-version: 22 - - - name: Install dependencies - run: | - npm ci --include=prod - - - name: Generate SBOM - run: | - curl -Lo $RUNNER_TEMP/sbom-tool https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-linux-x64 - chmod +x $RUNNER_TEMP/sbom-tool - - mkdir -p ./build - - $RUNNER_TEMP/sbom-tool generate -b ./build -bc . -pn ${DIST_FILE_NAME} -pv ${{ needs.release-please.outputs.release_version }} -ps "Ptarmigan Labs" -nsb https://sbom.ptarmiganlabs.com -V verbose - - - name: List generated SBOM files (debug) - run: | - echo "=== Build directory structure ===" - find ./build -type f -name "*.json" -o -name "*.spdx*" | head -20 - echo "=== File sizes ===" - find ./build -type f -name "*.json" -o -name "*.spdx*" -exec ls -la {} \; - - - name: Upload SBOM to Release - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - omitBodyDuringUpdate: true - omitNameDuringUpdate: true - # artifactContentType: raw - draft: true - artifacts: './build/**/*.spdx.json' - token: ${{ github.token }} - tag: ${{ needs.release-please.outputs.release_tag_name }} - - - name: Upload SBOM as Workflow Artifact (backup) - uses: actions/upload-artifact@v4 - with: - name: sbom-${{ needs.release-please.outputs.release_version }} - path: './build/' - retention-days: 90 - - release-macos-x64: - needs: release-please - runs-on: - - self-hosted - - x64 - - macos - - sp53 - # timeout-minutes: 15 - - if: needs.release-please.outputs.releases_created == 'true' - env: - DIST_FILE_NAME: butler-sos - 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 }} - steps: - - name: Release tag and upload url from previous job - run: | - echo "tag_name : ${{ needs.release-please.outputs.release_tag_name }}" - echo "version : ${{ needs.release-please.outputs.release_version }}" - echo "upload_url : ${{ needs.release-please.outputs.release_upload_url }}" - - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Setup Node.js - uses: actions/setup-node@v5 - with: - node-version: lts/* - - - name: Install tool for creating stand-alone executables - run: | - npm install --save-exact esbuild - - - name: Install dependencies - run: | - pwd - npm ci --include=prod - - - name: Build binaries - run: | - pwd - # Create a single JS file using esbuild - ./node_modules/.bin/esbuild src/bundle.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url - - # Generate blob to be injected into the binary - node --experimental-sea-config src/sea-config.json - - # Get a copy of the Node executable - cp $(command -v node) ${DIST_FILE_NAME} - - # Remove the signature from the Node executable - codesign --remove-signature ${DIST_FILE_NAME} - - # Inject the blob - 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 - - # Start signing of the binary - # ------------------- - # 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 - - # Turn our base64-encoded certificate back to a regular .p12 file - echo "DEBUG: Decoding certificate from base64" - echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 - - echo "DEBUG: Setting KEYCHAIN_NAME environment variable" - export KEYCHAIN_NAME="build.keychain" - - echo "DEBUG: Creating new keychain" - security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" - - echo "DEBUG: Getting current keychain list" - OLD_KEYCHAIN_NAMES=$(security list-keychains -d user | sed -e 's/"//g' | xargs) - echo "DEBUG: Current keychains: ${OLD_KEYCHAIN_NAMES}" - - echo "DEBUG: Setting keychain search list" - security list-keychains -d user -s "${KEYCHAIN_NAME}" ${OLD_KEYCHAIN_NAMES} - - echo "DEBUG: Getting current default keychain" - DEFAULT_KEYCHAIN=$(security default-keychain -d user | sed -e 's/"//g' | xargs) - echo "DEBUG: Default keychain is: ${DEFAULT_KEYCHAIN}" - - echo "DEBUG: Setting our keychain as default" - security default-keychain -d user -s "${KEYCHAIN_NAME}" - - echo "DEBUG: Unlocking keychain" - security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" - - echo "DEBUG: Importing certificate into keychain" - security import certificate.p12 -k "${KEYCHAIN_NAME}" -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign - - echo "DEBUG: Setting keychain timeout to prevent locking" - security set-keychain-settings -t 3600 -l "${KEYCHAIN_NAME}" - - echo "DEBUG: Setting key partition list" - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" - - echo "DEBUG: Performing codesign operation" - codesign --force -s "$MACOS_CERTIFICATE_NAME" -v "./${DIST_FILE_NAME}" --deep --strict --options=runtime --timestamp --entitlements ./release-config/${DIST_FILE_NAME}.entitlements - - echo "DEBUG: Verifying code signature" - codesign -vvv --deep --strict "./${DIST_FILE_NAME}" - - # ------------------- - # Notarize - # Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI - echo "Create keychain profile" - # Get the absolute path to the keychain in ~/Library/Keychains/ with the -db suffix macOS adds to keychain files - KEYCHAIN_PATH=~/Library/Keychains/${KEYCHAIN_NAME}-db - echo "DEBUG: Using keychain at path: ${KEYCHAIN_PATH}" - 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" --keychain "${KEYCHAIN_PATH}" - - # ------------------- - # 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" - zip -r "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" "./${DIST_FILE_NAME}" -x "*.DS_Store" - - # Add additional files to the zip file - cd src - zip -u -r "../${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" "./config/production_template.yaml" "./config/log_appender_xml" -x "*.DS_Store" - cd .. - - # Here we send the notarization request to the Apple's Notarization service, waiting for the result. - echo "Notarize insider app" - xcrun notarytool submit "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" --keychain-profile "notarytool-profile" --wait --keychain "${KEYCHAIN_PATH}" - - echo "DEBUG: Restoring original default keychain" - security default-keychain -d user -s "$DEFAULT_KEYCHAIN" || echo "WARNING: Failed to restore default keychain, continuing anyway" - - echo "DEBUG: Restoring original keychain list" - security list-keychains -d user -s ${OLD_KEYCHAIN_NAMES} || echo "WARNING: Failed to restore keychain list, continuing anyway" - - # ------------------- - # Clean up - # Delete build keychain - security delete-keychain build.keychain - - ls -la - - - name: Upload to existing release - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - omitBodyDuringUpdate: true - omitNameDuringUpdate: true - artifactContentType: raw - # artifactContentType: application/zip - draft: true - tag: ${{ needs.release-please.outputs.release_tag_name }} - artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-macos-x64.zip - token: ${{ github.token }} - - - name: Tidy up before existing - run: | - pwd - ls -la - rm build.cjs certificate.p12 - rm "./${DIST_FILE_NAME}" - rm "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" - - release-macos-arm64: - needs: release-please - runs-on: - - self-hosted - - arm64 - - macos - - sp53 - # timeout-minutes: 15 - - if: needs.release-please.outputs.releases_created == 'true' - env: - DIST_FILE_NAME: butler-sos - 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 }} - steps: - - name: Release tag and upload url from previous job - run: | - echo "tag_name : ${{ needs.release-please.outputs.release_tag_name }}" - echo "version : ${{ needs.release-please.outputs.release_version }}" - echo "upload_url : ${{ needs.release-please.outputs.release_upload_url }}" - - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Setup Node.js - uses: actions/setup-node@v5 - with: - node-version: lts/* - - - name: Install tool for creating stand-alone executables - run: | - npm install --save-exact esbuild - - - name: Install dependencies - run: | - pwd - npm ci --include=prod - - - name: Build binaries - run: | - pwd - # Create a single JS file using esbuild - ./node_modules/.bin/esbuild src/bundle.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url - - # Generate blob to be injected into the binary - node --experimental-sea-config src/sea-config.json - - # Get a copy of the Node executable - cp $(command -v node) ${DIST_FILE_NAME} - - # Remove the signature from the Node executable - codesign --remove-signature ${DIST_FILE_NAME} - - # Inject the blob - 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 - - # Start signing of the binary - - # ------------------- - # 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 - - # Turn our base64-encoded certificate back to a regular .p12 file - echo "DEBUG: Decoding certificate from base64" - echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 - - echo "DEBUG: Setting KEYCHAIN_NAME environment variable" - export KEYCHAIN_NAME="build.keychain" - - echo "DEBUG: Creating new keychain" - security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" - - echo "DEBUG: Getting current keychain list" - OLD_KEYCHAIN_NAMES=$(security list-keychains -d user | sed -e 's/"//g' | xargs) - echo "DEBUG: Current keychains: ${OLD_KEYCHAIN_NAMES}" - - echo "DEBUG: Setting keychain search list" - security list-keychains -d user -s "${KEYCHAIN_NAME}" ${OLD_KEYCHAIN_NAMES} - - echo "DEBUG: Getting current default keychain" - DEFAULT_KEYCHAIN=$(security default-keychain -d user | sed -e 's/"//g' | xargs) - echo "DEBUG: Default keychain is: ${DEFAULT_KEYCHAIN}" - - echo "DEBUG: Setting our keychain as default" - security default-keychain -d user -s "${KEYCHAIN_NAME}" - - echo "DEBUG: Unlocking keychain" - security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" - - echo "DEBUG: Importing certificate into keychain" - security import certificate.p12 -k "${KEYCHAIN_NAME}" -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign - - echo "DEBUG: Setting keychain timeout to prevent locking" - security set-keychain-settings -t 3600 -l "${KEYCHAIN_NAME}" - - echo "DEBUG: Setting key partition list" - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" - - echo "DEBUG: Performing codesign operation" - codesign --force -s "$MACOS_CERTIFICATE_NAME" -v "./${DIST_FILE_NAME}" --deep --strict --options=runtime --timestamp --entitlements ./release-config/${DIST_FILE_NAME}.entitlements - - echo "DEBUG: Verifying code signature" - codesign -vvv --deep --strict "./${DIST_FILE_NAME}" - - # ------------------- - # Notarize - # Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI - echo "Create keychain profile" - # Get the absolute path to the keychain in ~/Library/Keychains/ with the -db suffix macOS adds to keychain files - KEYCHAIN_PATH=~/Library/Keychains/${KEYCHAIN_NAME}-db - echo "DEBUG: Using keychain at path: ${KEYCHAIN_PATH}" - 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" --keychain "${KEYCHAIN_PATH}" - - # ------------------- - # 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" - zip -r "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" "./${DIST_FILE_NAME}" -x "*.DS_Store" - - # Add additional files to the zip file - cd src - zip -u -r "../${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" "./config/production_template.yaml" "./config/log_appender_xml" -x "*.DS_Store" - cd .. - - # Here we send the notarization request to the Apple's Notarization service, waiting for the result. - echo "Notarize insider app" - xcrun notarytool submit "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" --keychain-profile "notarytool-profile" --wait --keychain "${KEYCHAIN_PATH}" - - echo "DEBUG: Restoring original default keychain" - security default-keychain -d user -s "$DEFAULT_KEYCHAIN" || echo "WARNING: Failed to restore default keychain, continuing anyway" - - echo "DEBUG: Restoring original keychain list" - security list-keychains -d user -s ${OLD_KEYCHAIN_NAMES} || echo "WARNING: Failed to restore keychain list, continuing anyway" - - # ------------------- - # Clean up - # Delete build keychain - security delete-keychain build.keychain - - ls -la - - - name: Upload to existing release - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - omitBodyDuringUpdate: true - omitNameDuringUpdate: true - artifactContentType: raw - # artifactContentType: application/zip - draft: true - tag: ${{ needs.release-please.outputs.release_tag_name }} - artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip - token: ${{ github.token }} - - - name: Tidy up before existing - run: | - pwd - ls -la - rm build.cjs certificate.p12 - rm "./${DIST_FILE_NAME}" - rm "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" - - release-win64: - needs: release-please - runs-on: - - self-hosted - - x64 - - windows - - sp53 - - win-code-sign - # timeout-minutes: 15 - if: needs.release-please.outputs.releases_created == 'true' - env: - DIST_FILE_NAME: butler-sos - GITHUB_TOKEN: ${{ secrets.PAT }} - # CODESIGN_PWD: ${{ secrets.WIN_CODESIGN_PWD}} - # CODESIGN_INTERMEDIATE_BASE64: ${{ secrets.WIN_CODESIGN_INTERMEDIATE_BASE64 }} - # CODESIGN_BASE64: ${{ secrets.WIN_CODESIGN_BASE64}} - CODESIGN_WIN_THUMBPRINT: ${{ secrets.WIN_CODESIGN_THUMBPRINT}} - steps: - - name: Release tag and upload url from previous job - run: | - Write-Output 'tag_name : ${{ needs.release-please.outputs.release_tag_name }}' - Write-Output 'version : ${{ needs.release-please.outputs.release_version }}' - Write-Output 'upload_url : ${{ needs.release-please.outputs.release_upload_url }}' - - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Setup Node.js - uses: actions/setup-node@v5 - with: - node-version: lts/* - - - name: Install tool for creating stand-alone executables - run: | - npm install --save-exact esbuild - - - name: Install dependencies - run: | - pwd - npm ci --include=prod - - - name: Build binaries - run: | - # Create a single JS file using esbuild - ./node_modules/.bin/esbuild "src/bundle.js" --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url - - # Generate blob to be injected into the binary - node --experimental-sea-config src/sea-config.json - - # Get a copy of the Node executable - 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}-${{ needs.release-please.outputs.release_version }}-win.zip" - } - Compress-Archive @compress - - # Add following directories & files to the created zip file, in the ./config directory. - # - ./src/config/production_template.yaml - # - ./src/config/log_appender_xml - mkdir config - Copy-Item -Path ./src/config/log_appender_xml -Destination ./config/ -Recurse - Copy-Item -Path ./src/config/production_template.yaml -Destination ./config/ - - Compress-Archive -Path "./config" -Update -DestinationPath "./${env:DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-win.zip" - - - # ------------------- - # Clean up - - dir - - - name: Upload to existing release - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - omitBodyDuringUpdate: true - omitNameDuringUpdate: true - artifactContentType: raw - # artifactContentType: application/zip - draft: true - tag: ${{ needs.release-please.outputs.release_tag_name }} - artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-win.zip - token: ${{ github.token }} - - - name: Tidy up before existing - run: | - dir - Remove-Item -Force build.cjs - Remove-Item -Force "./${env:DIST_FILE_NAME}.exe" - Remove-Item -Force "./${env:DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-win.zip" - - release-linux: - needs: release-please - runs-on: ubuntu-latest - # timeout-minutes: 15 - - if: needs.release-please.outputs.releases_created == 'true' - env: - DIST_FILE_NAME: butler-sos - GITHUB_TOKEN: ${{ secrets.PAT }} - steps: - - name: Release tag and upload url from previous job - run: | - echo "tag_name : ${{ needs.release-please.outputs.release_tag_name }}" - echo "version : ${{ needs.release-please.outputs.release_version }}" - echo "upload_url : ${{ needs.release-please.outputs.release_upload_url }}" - - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Setup Node.js - uses: actions/setup-node@v5 - with: - node-version: lts/* - - - name: Install tool for creating stand-alone executables - run: | - npm install --save-exact esbuild - - - name: Install dependencies - run: | - pwd - npm ci --include=prod - - - name: Build binaries - run: | - ./node_modules/.bin/esbuild src/bundle.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url - node --experimental-sea-config src/sea-config.json - - # Get a copy of the Node executable - cp $(command -v node) ${DIST_FILE_NAME} - npx postject ${DIST_FILE_NAME} NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 - - # Make binary executable - chmod +x ./${DIST_FILE_NAME} - - - name: Compress the created binary - run: | - # Include following directories & files in the created archive file. - # - ./src/config/log_appender_xml - # - ./src/config⁄production_template.yaml - ls -la - echo "Creating zip file" - zip -9 -r ./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-linux-x64.zip ${DIST_FILE_NAME} - - # Add additional files to the zip file - cd src - echo "Adding additional files" - zip -9 -u -r "../${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-linux-x64.zip" "./config/production_template.yaml" "./config/log_appender_xml" - - ls -la - - - name: Upload to existing release - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - omitBodyDuringUpdate: true - omitNameDuringUpdate: true - artifactContentType: raw - # artifactContentType: application/zip - draft: true - tag: ${{ needs.release-please.outputs.release_tag_name }} - artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-linux-x64.zip - token: ${{ github.token }} - - - name: Tidy up before existing - run: | - pwd - ls -la - rm build.cjs - rm "./${DIST_FILE_NAME}" - rm "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-linux-x64.zip" + RELEASE_PLEASE_OUTPUT: ${{ toJSON(steps.release.outputs) }} + run: echo "$RELEASE_PLEASE_OUTPUT" + + - name: Show output from Release-Please + run: | + echo "releases_created: ${{ steps.release.outputs.releases_created }}" + echo "release_created : ${{ steps.release.outputs.release_created }}" + echo "draft : ${{ steps.release.outputs['draft'] }}" + echo "path : ${{ steps.release.outputs['path'] }}" + echo "upload_url : ${{ steps.release.outputs['upload_url'] }}" + echo "html_url : ${{ steps.release.outputs['html_url'] }}" + echo "tag_name : ${{ steps.release.outputs['tag_name'] }}" + echo "version : ${{ steps.release.outputs['version'] }}" + echo "major : ${{ steps.release.outputs['major'] }}" + echo "minor : ${{ steps.release.outputs['minor'] }}" + echo "patch : ${{ steps.release.outputs['patch'] }}" + echo "sha : ${{ steps.release.outputs['sha'] }}" + + sbom-build: + needs: release-please + runs-on: ubuntu-latest + + if: needs.release-please.outputs.releases_created == 'true' + env: + DIST_FILE_NAME: butler-sos + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: 22 + + - name: Install dependencies + run: | + npm ci --include=prod + + - name: Generate SBOM + run: | + curl -Lo $RUNNER_TEMP/sbom-tool https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-linux-x64 + chmod +x $RUNNER_TEMP/sbom-tool + + mkdir -p ./build + + $RUNNER_TEMP/sbom-tool generate -b ./build -bc . -pn ${DIST_FILE_NAME} -pv ${{ needs.release-please.outputs.release_version }} -ps "Ptarmigan Labs" -nsb https://sbom.ptarmiganlabs.com -V verbose + + - name: List generated SBOM files (debug) + run: | + echo "=== Build directory structure ===" + find ./build -type f -name "*.json" -o -name "*.spdx*" | head -20 + echo "=== File sizes ===" + find ./build -type f -name "*.json" -o -name "*.spdx*" -exec ls -la {} \; + + - name: Upload SBOM to Release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + # artifactContentType: raw + draft: true + artifacts: './build/**/*.spdx.json' + token: ${{ github.token }} + tag: ${{ needs.release-please.outputs.release_tag_name }} + + - name: Upload SBOM as Workflow Artifact (backup) + uses: actions/upload-artifact@v4 + with: + name: sbom-${{ needs.release-please.outputs.release_version }} + path: './build/' + retention-days: 3 + + release-macos-x64: + needs: release-please + runs-on: + - self-hosted + - x64s + - macos + - sp53 + # timeout-minutes: 15 + + if: needs.release-please.outputs.releases_created == 'true' + env: + DIST_FILE_NAME: butler-sos + 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 }} + steps: + - name: Release tag and upload url from previous job + run: | + echo "tag_name : ${{ needs.release-please.outputs.release_tag_name }}" + echo "version : ${{ needs.release-please.outputs.release_version }}" + echo "upload_url : ${{ needs.release-please.outputs.release_upload_url }}" + + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: lts/* + + - name: Install tool for creating stand-alone executables + run: | + npm install --save-exact esbuild + + - name: Install dependencies + run: | + pwd + npm ci --include=prod + + - name: Build binaries + run: | + pwd + # Create a single JS file using esbuild + ./node_modules/.bin/esbuild src/bundle.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url + + # Generate blob to be injected into the binary + node --experimental-sea-config src/sea-config.json + + # Get a copy of the Node executable + cp $(command -v node) ${DIST_FILE_NAME} + + # Remove the signature from the Node executable + codesign --remove-signature ${DIST_FILE_NAME} + + # Inject the blob + 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 + + # Start signing of the binary + # ------------------- + # 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 + + # Turn our base64-encoded certificate back to a regular .p12 file + echo "DEBUG: Decoding certificate from base64" + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + + echo "DEBUG: Setting KEYCHAIN_NAME environment variable" + export KEYCHAIN_NAME="build.keychain" + + echo "DEBUG: Creating new keychain" + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" + + echo "DEBUG: Getting current keychain list" + OLD_KEYCHAIN_NAMES=$(security list-keychains -d user | sed -e 's/"//g' | xargs) + echo "DEBUG: Current keychains: ${OLD_KEYCHAIN_NAMES}" + + echo "DEBUG: Setting keychain search list" + security list-keychains -d user -s "${KEYCHAIN_NAME}" ${OLD_KEYCHAIN_NAMES} + + echo "DEBUG: Getting current default keychain" + DEFAULT_KEYCHAIN=$(security default-keychain -d user | sed -e 's/"//g' | xargs) + echo "DEBUG: Default keychain is: ${DEFAULT_KEYCHAIN}" + + echo "DEBUG: Setting our keychain as default" + security default-keychain -d user -s "${KEYCHAIN_NAME}" + + echo "DEBUG: Unlocking keychain" + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" + + echo "DEBUG: Importing certificate into keychain" + security import certificate.p12 -k "${KEYCHAIN_NAME}" -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + + echo "DEBUG: Setting keychain timeout to prevent locking" + security set-keychain-settings -t 3600 -l "${KEYCHAIN_NAME}" + + echo "DEBUG: Setting key partition list" + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" + + echo "DEBUG: Performing codesign operation" + codesign --force -s "$MACOS_CERTIFICATE_NAME" -v "./${DIST_FILE_NAME}" --deep --strict --options=runtime --timestamp --entitlements ./release-config/${DIST_FILE_NAME}.entitlements + + echo "DEBUG: Verifying code signature" + codesign -vvv --deep --strict "./${DIST_FILE_NAME}" + + # ------------------- + # Notarize + # Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI + echo "Create keychain profile" + # Get the absolute path to the keychain in ~/Library/Keychains/ with the -db suffix macOS adds to keychain files + KEYCHAIN_PATH=~/Library/Keychains/${KEYCHAIN_NAME}-db + echo "DEBUG: Using keychain at path: ${KEYCHAIN_PATH}" + 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" --keychain "${KEYCHAIN_PATH}" + + # ------------------- + # 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" + zip -r "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" "./${DIST_FILE_NAME}" -x "*.DS_Store" + + # Add additional files to the zip file + cd src + zip -u -r "../${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" "./config/production_template.yaml" "./config/log_appender_xml" -x "*.DS_Store" + cd .. + + # Here we send the notarization request to the Apple's Notarization service, waiting for the result. + echo "Notarize insider app" + xcrun notarytool submit "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" --keychain-profile "notarytool-profile" --wait --keychain "${KEYCHAIN_PATH}" + + echo "DEBUG: Restoring original default keychain" + security default-keychain -d user -s "$DEFAULT_KEYCHAIN" || echo "WARNING: Failed to restore default keychain, continuing anyway" + + echo "DEBUG: Restoring original keychain list" + security list-keychains -d user -s ${OLD_KEYCHAIN_NAMES} || echo "WARNING: Failed to restore keychain list, continuing anyway" + + # ------------------- + # Clean up + # Delete build keychain + security delete-keychain build.keychain + + ls -la + + - name: Upload to existing release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + artifactContentType: raw + # artifactContentType: application/zip + draft: true + tag: ${{ needs.release-please.outputs.release_tag_name }} + artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-macos-x64.zip + token: ${{ github.token }} + + - name: Tidy up before existing + run: | + pwd + ls -la + rm build.cjs certificate.p12 + rm "./${DIST_FILE_NAME}" + rm "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-x64.zip" + + release-macos-arm64: + needs: release-please + runs-on: + - self-hosted + - arm64 + - macos + - sp53 + # timeout-minutes: 15 + + if: needs.release-please.outputs.releases_created == 'true' + env: + DIST_FILE_NAME: butler-sos + 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 }} + steps: + - name: Release tag and upload url from previous job + run: | + echo "tag_name : ${{ needs.release-please.outputs.release_tag_name }}" + echo "version : ${{ needs.release-please.outputs.release_version }}" + echo "upload_url : ${{ needs.release-please.outputs.release_upload_url }}" + + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: lts/* + + - name: Install tool for creating stand-alone executables + run: | + npm install --save-exact esbuild + + - name: Install dependencies + run: | + pwd + npm ci --include=prod + + - name: Build binaries + run: | + pwd + # Create a single JS file using esbuild + ./node_modules/.bin/esbuild src/bundle.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url + + # Generate blob to be injected into the binary + node --experimental-sea-config src/sea-config.json + + # Get a copy of the Node executable + cp $(command -v node) ${DIST_FILE_NAME} + + # Remove the signature from the Node executable + codesign --remove-signature ${DIST_FILE_NAME} + + # Inject the blob + 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 + + # Start signing of the binary + + # ------------------- + # 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 + + # Turn our base64-encoded certificate back to a regular .p12 file + echo "DEBUG: Decoding certificate from base64" + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + + echo "DEBUG: Setting KEYCHAIN_NAME environment variable" + export KEYCHAIN_NAME="build.keychain" + + echo "DEBUG: Creating new keychain" + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" + + echo "DEBUG: Getting current keychain list" + OLD_KEYCHAIN_NAMES=$(security list-keychains -d user | sed -e 's/"//g' | xargs) + echo "DEBUG: Current keychains: ${OLD_KEYCHAIN_NAMES}" + + echo "DEBUG: Setting keychain search list" + security list-keychains -d user -s "${KEYCHAIN_NAME}" ${OLD_KEYCHAIN_NAMES} + + echo "DEBUG: Getting current default keychain" + DEFAULT_KEYCHAIN=$(security default-keychain -d user | sed -e 's/"//g' | xargs) + echo "DEBUG: Default keychain is: ${DEFAULT_KEYCHAIN}" + + echo "DEBUG: Setting our keychain as default" + security default-keychain -d user -s "${KEYCHAIN_NAME}" + + echo "DEBUG: Unlocking keychain" + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" + + echo "DEBUG: Importing certificate into keychain" + security import certificate.p12 -k "${KEYCHAIN_NAME}" -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + + echo "DEBUG: Setting keychain timeout to prevent locking" + security set-keychain-settings -t 3600 -l "${KEYCHAIN_NAME}" + + echo "DEBUG: Setting key partition list" + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" "${KEYCHAIN_NAME}" + + echo "DEBUG: Performing codesign operation" + codesign --force -s "$MACOS_CERTIFICATE_NAME" -v "./${DIST_FILE_NAME}" --deep --strict --options=runtime --timestamp --entitlements ./release-config/${DIST_FILE_NAME}.entitlements + + echo "DEBUG: Verifying code signature" + codesign -vvv --deep --strict "./${DIST_FILE_NAME}" + + # ------------------- + # Notarize + # Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI + echo "Create keychain profile" + # Get the absolute path to the keychain in ~/Library/Keychains/ with the -db suffix macOS adds to keychain files + KEYCHAIN_PATH=~/Library/Keychains/${KEYCHAIN_NAME}-db + echo "DEBUG: Using keychain at path: ${KEYCHAIN_PATH}" + 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" --keychain "${KEYCHAIN_PATH}" + + # ------------------- + # 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" + zip -r "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" "./${DIST_FILE_NAME}" -x "*.DS_Store" + + # Add additional files to the zip file + cd src + zip -u -r "../${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" "./config/production_template.yaml" "./config/log_appender_xml" -x "*.DS_Store" + cd .. + + # Here we send the notarization request to the Apple's Notarization service, waiting for the result. + echo "Notarize insider app" + xcrun notarytool submit "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" --keychain-profile "notarytool-profile" --wait --keychain "${KEYCHAIN_PATH}" + + echo "DEBUG: Restoring original default keychain" + security default-keychain -d user -s "$DEFAULT_KEYCHAIN" || echo "WARNING: Failed to restore default keychain, continuing anyway" + + echo "DEBUG: Restoring original keychain list" + security list-keychains -d user -s ${OLD_KEYCHAIN_NAMES} || echo "WARNING: Failed to restore keychain list, continuing anyway" + + # ------------------- + # Clean up + # Delete build keychain + security delete-keychain build.keychain + + ls -la + + - name: Upload to existing release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + artifactContentType: raw + # artifactContentType: application/zip + draft: true + tag: ${{ needs.release-please.outputs.release_tag_name }} + artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip + token: ${{ github.token }} + + - name: Tidy up before existing + run: | + pwd + ls -la + rm build.cjs certificate.p12 + rm "./${DIST_FILE_NAME}" + rm "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-macos-arm64.zip" + + release-win64: + needs: release-please + runs-on: + - self-hosted + - x64 + - windows + - sp53 + - win-code-sign + # timeout-minutes: 15 + if: needs.release-please.outputs.releases_created == 'true' + env: + DIST_FILE_NAME: butler-sos + GITHUB_TOKEN: ${{ secrets.PAT }} + # CODESIGN_PWD: ${{ secrets.WIN_CODESIGN_PWD}} + # CODESIGN_INTERMEDIATE_BASE64: ${{ secrets.WIN_CODESIGN_INTERMEDIATE_BASE64 }} + # CODESIGN_BASE64: ${{ secrets.WIN_CODESIGN_BASE64}} + CODESIGN_WIN_THUMBPRINT: ${{ secrets.WIN_CODESIGN_THUMBPRINT}} + steps: + - name: Release tag and upload url from previous job + run: | + Write-Output 'tag_name : ${{ needs.release-please.outputs.release_tag_name }}' + Write-Output 'version : ${{ needs.release-please.outputs.release_version }}' + Write-Output 'upload_url : ${{ needs.release-please.outputs.release_upload_url }}' + + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: lts/* + + - name: Install tool for creating stand-alone executables + run: | + npm install --save-exact esbuild + + - name: Install dependencies + run: | + pwd + npm ci --include=prod + + - name: Build binaries + run: | + # Create a single JS file using esbuild + ./node_modules/.bin/esbuild "src/bundle.js" --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url + + # Generate blob to be injected into the binary + node --experimental-sea-config src/sea-config.json + + # Get a copy of the Node executable + 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}-${{ needs.release-please.outputs.release_version }}-win.zip" + } + Compress-Archive @compress + + # Add following directories & files to the created zip file, in the ./config directory. + # - ./src/config/production_template.yaml + # - ./src/config/log_appender_xml + mkdir config + Copy-Item -Path ./src/config/log_appender_xml -Destination ./config/ -Recurse + Copy-Item -Path ./src/config/production_template.yaml -Destination ./config/ + + Compress-Archive -Path "./config" -Update -DestinationPath "./${env:DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-win.zip" + + + # ------------------- + # Clean up + + dir + + - name: Upload to existing release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + artifactContentType: raw + # artifactContentType: application/zip + draft: true + tag: ${{ needs.release-please.outputs.release_tag_name }} + artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-win.zip + token: ${{ github.token }} + + - name: Tidy up before existing + run: | + dir + Remove-Item -Force build.cjs + Remove-Item -Force "./${env:DIST_FILE_NAME}.exe" + Remove-Item -Force "./${env:DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-win.zip" + + release-linux: + needs: release-please + runs-on: ubuntu-latest + # timeout-minutes: 15 + + if: needs.release-please.outputs.releases_created == 'true' + env: + DIST_FILE_NAME: butler-sos + GITHUB_TOKEN: ${{ secrets.PAT }} + steps: + - name: Release tag and upload url from previous job + run: | + echo "tag_name : ${{ needs.release-please.outputs.release_tag_name }}" + echo "version : ${{ needs.release-please.outputs.release_version }}" + echo "upload_url : ${{ needs.release-please.outputs.release_upload_url }}" + + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: lts/* + + - name: Install tool for creating stand-alone executables + run: | + npm install --save-exact esbuild + + - name: Install dependencies + run: | + pwd + npm ci --include=prod + + - name: Build binaries + run: | + ./node_modules/.bin/esbuild src/bundle.js --bundle --outfile=build.cjs --format=cjs --platform=node --target=node22 --inject:./src/lib/import-meta-url.js --define:import.meta.url=import_meta_url + node --experimental-sea-config src/sea-config.json + + # Get a copy of the Node executable + cp $(command -v node) ${DIST_FILE_NAME} + npx postject ${DIST_FILE_NAME} NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 + + # Make binary executable + chmod +x ./${DIST_FILE_NAME} + + - name: Compress the created binary + run: | + # Include following directories & files in the created archive file. + # - ./src/config/log_appender_xml + # - ./src/config⁄production_template.yaml + ls -la + echo "Creating zip file" + zip -9 -r ./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-linux-x64.zip ${DIST_FILE_NAME} + + # Add additional files to the zip file + cd src + echo "Adding additional files" + zip -9 -u -r "../${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-linux-x64.zip" "./config/production_template.yaml" "./config/log_appender_xml" + + ls -la + + - name: Upload to existing release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + artifactContentType: raw + # artifactContentType: application/zip + draft: true + tag: ${{ needs.release-please.outputs.release_tag_name }} + artifacts: ./butler-sos-${{ needs.release-please.outputs.release_version }}-linux-x64.zip + token: ${{ github.token }} + + - name: Tidy up before existing + run: | + pwd + ls -la + rm build.cjs + rm "./${DIST_FILE_NAME}" + rm "./${DIST_FILE_NAME}-${{ needs.release-please.outputs.release_version }}-linux-x64.zip"