name: Release Build on: workflow_dispatch: permissions: {} concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: # shared kong github action for security checking generate-sbom-and-upload-assets: if: startsWith(github.ref_name, 'release/') runs-on: ubuntu-24.04 permissions: contents: read # Required for actions/checkout steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # Perform SCA / SBOM analysis for the entire monorepo code repository # Produces SCA(SBOM and CVE) report # Helps understand vulnerabilities / license compliance across third party dependencies # Automatically uploads to workflow assets # (TODO): Produce workspace/package specific SBOM. Current limitation: https://github.com/anchore/syft/issues/2574 # (TODO): needs check (block) further steps if SCA fails - id: sca-project uses: Kong/public-shared-actions/security-actions/sca@a18abf762d6e2444bcbfd20de70451ea1e3bc1b1 # v4.1.1 with: dir: . upload-sbom-release-assets: false build-and-upload-release-artifacts: if: startsWith(github.ref_name, 'release/') timeout-minutes: 45 runs-on: ${{ matrix.os }} permissions: contents: read packages: read env: INSO_PACKAGE_NAME: insomnia-inso INSO_DOCKER_TAR: inso-docker-image.tar # DIGICERT_SM_CLIENT_CERT_FILE: sm_client_cert.p12 # DIGICERT_WIN_SM_CLIENT_CERT_FILE: /d/a/insomnia-ee/insomnia-ee/sm_client_cert.p12 strategy: fail-fast: false matrix: include: - os: macos-latest-large csc_link_secret: DESIGNER_MAC_CSC_LINK csc_key_password_secret: DESIGNER_MAC_CSC_KEY_PASSWORD - os: windows-latest csc_link_secret: '' csc_key_password_secret: '' - os: ubuntu-24.04 csc_link_secret: '' csc_key_password_secret: '' # - os: ubuntu-24.04-arm # csc_link_secret: '' # csc_key_password_secret: '' steps: - name: Checkout branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: '.nvmrc' cache: 'npm' cache-dependency-path: package-lock.json registry-url: 'https://npm.pkg.github.com' scope: '@kong' - name: Install packages run: npm ci env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' - name: Setup Inso CLI version env var shell: bash run: | echo "INSO_VERSION=$(jq .version ./packages/${{ env.INSO_PACKAGE_NAME }}/package.json -rj)" >> $GITHUB_ENV - name: Package app (Linux ARM64 only) if: runner.os == 'Linux' && runner.arch == 'ARM64' shell: bash run: npm run app-package env: NODE_OPTIONS: '--max_old_space_size=6144' BUILD_TARGETS: AppImage,tar.gz - name: Package app (Linux X64 only) if: runner.os == 'Linux' && runner.arch == 'X64' shell: bash run: npm run app-package env: NODE_OPTIONS: '--max_old_space_size=6144' # If this step fails its possible apple has new license terms which need to be accepted by logging into https://developer.apple.com/account - name: Package app (MacOS only) if: runner.os == 'macOS' shell: bash run: npm run app-package env: NODE_OPTIONS: '--max_old_space_size=6144' APPLE_ID: ${{ runner.os == 'macOS' && secrets.DESIGNER_APPLE_ID || '' }} APPLE_APP_SPECIFIC_PASSWORD: ${{ runner.os == 'macOS' && secrets.DESIGNER_APPLE_ID_PASSWORD || '' }} APPLE_TEAM_ID: FX44YY62GV CSC_LINK: ${{ matrix.csc_link_secret != '' && secrets[matrix.csc_link_secret] || '' }} CSC_KEY_PASSWORD: ${{ matrix.csc_key_password_secret != '' && secrets[matrix.csc_key_password_secret] || '' }} - name: Setup DIGICERT_SM_CLIENT_CERT_FILE from base64 secret data if: runner.os == 'Windows' shell: bash run: | echo "${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12 - name: Set variables id: variables run: | echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV" shell: bash # This will install smctl # smctl will be used in the next step for signing - name: Setup Software Trust Manager if: runner.os == 'Windows' uses: digicert/code-signing-software-trust-action@fae23a455ba4bde62b64fd7cb2f81ade788f5a95 # v1.2.1 with: simple-signing-mode: true env: SM_HOST: ${{ vars.DIGICERT_SM_HOST }} SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }} SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }} # creates unpacked electron-builder contents that can be signed afterwards - name: Package unpacked app (Windows only) if: runner.os == 'Windows' shell: bash run: | # smctl credentials save ${SM_API_KEY} ${SM_CLIENT_CERT_PASSWORD} NODE_OPTIONS='--max_old_space_size=6144' npm run package:windows:unpacked -w insomnia env: SM_HOST: ${{ vars.DIGICERT_SM_HOST }} SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }} SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }} SM_KEYPAIR_ALIAS: ${{ secrets.DIGICERT_KEYPAIR_ALIAS }} # wraps the Insomnia.exe PE with another PE that will bootstrap particular security # features added to Windows 8 in order to stopgap CVE-2025-1353 - name: Compile secure wrapper (Windows only) if: runner.os == 'Windows' shell: bash run: ./build-secure-wrapper.sh CI - name: Move .dll and .exe files to /tosign (PowerShell) if: runner.os == 'Windows' shell: pwsh run: | New-Item -Path "packages/insomnia/dist/win-unpacked/tosign" -ItemType Directory -Force Get-ChildItem -Path "packages/insomnia/dist/win-unpacked" -Filter *.dll | Move-Item -Destination "packages/insomnia/dist/win-unpacked/tosign" Get-ChildItem -Path "packages/insomnia/dist/win-unpacked" -Filter *.exe | Move-Item -Destination "packages/insomnia/dist/win-unpacked/tosign" # signs unpacked electron-builder contents, in this case only the .exe # this installs smctl as well - name: Code-sign unpacked .exe (Windows only) if: runner.os == 'Windows' uses: digicert/code-signing-software-trust-action@fae23a455ba4bde62b64fd7cb2f81ade788f5a95 # v1.2.1 with: simple-signing-mode: true # If the below 2 parameters are supplied, then smctl executable is invoked to attempt the signing. input: packages/insomnia/dist/win-unpacked/tosign keypair-alias: ${{ secrets.DIGICERT_KEYPAIR_ALIAS }} env: SM_HOST: ${{ vars.DIGICERT_SM_HOST }} SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }} SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }} - name: Move .dll and .exe files back to win-unpacked and delete /tosign if: runner.os == 'Windows' shell: pwsh run: | Get-ChildItem -Path "packages/insomnia/dist/win-unpacked/tosign" -Filter *.dll | Move-Item -Destination "packages/insomnia/dist/win-unpacked" Get-ChildItem -Path "packages/insomnia/dist/win-unpacked/tosign" -Filter *.exe | Move-Item -Destination "packages/insomnia/dist/win-unpacked" Remove-Item -Path "packages/insomnia/dist/win-unpacked/tosign" -Recurse -Force # re-packages the now code-signed electron-builder contents into the installer - name: Package dist app (Windows only) if: runner.os == 'Windows' shell: bash run: | NODE_OPTIONS='--max_old_space_size=6144' npm run package:windows:dist -w insomnia env: SM_HOST: ${{ vars.DIGICERT_SM_HOST }} SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }} SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }} SM_KEYPAIR_ALIAS: ${{ secrets.DIGICERT_KEYPAIR_ALIAS }} - name: Check squirrel exe signature (Windows only) if: runner.os == 'Windows' shell: pwsh run: | $version = $env:INSO_VERSION # https://github.com/electron/windows-installer/blob/main/src/index.ts#L25 (convert version to NuGet-compatible) $nupkgVersion = $version -replace "-([a-zA-Z]+)\.", '-$1' $nupkg = "insomnia-${nupkgVersion}-full.nupkg" Write-Host "scan insomnia-${nupkgVersion}-full.nupkg" 7z x "packages/insomnia/dist/squirrel-windows/${nupkg}" -o"${version}-extract" $exeFiles = Get-ChildItem -Path "${version}-extract/lib/net45" -Filter *.exe if ($exeFiles.Count -eq 0) { Write-Warning "No .exe files found in the package" exit 1 } Write-Host "Found $($exeFiles.Count) .exe file(s):" Write-Host "" foreach ($exe in $exeFiles) { Write-Host "Checking: $($exe.Name)" Write-Host " Path: $($exe.FullName)" $signature = Get-AuthenticodeSignature -FilePath $exe.FullName Write-Host " Status: $($signature.Status)" Write-Host " Signer: $($signature.SignerCertificate.Subject)" Write-Host " Timestamp: $($signature.TimeStamperCertificate.NotAfter)" if ($signature.Status -ne 'Valid') { Write-Error " ❌ Invalid signature for $($exe.Name)" exit 1 } Write-Host " ✓ Valid signature" -ForegroundColor Green } Write-Host "✓ All executables are properly signed" -ForegroundColor Green - name: Package inso run: | npm run install-libcurl-node npm run build:production -w insomnia-inso npm run package -w insomnia-inso env: VERSION: ${{ env.INSO_VERSION }} - name: Code-sign inso exe (Windows only) if: runner.os == 'Windows' uses: digicert/code-signing-software-trust-action@fae23a455ba4bde62b64fd7cb2f81ade788f5a95 # v1.2.1 with: simple-signing-mode: true # If the below 2 parameters are supplied, then smctl executable is invoked to attempt the signing. input: packages/insomnia-inso/binaries/inso.exe keypair-alias: ${{ secrets.DIGICERT_KEYPAIR_ALIAS }} env: SM_HOST: ${{ vars.DIGICERT_SM_HOST }} SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }} SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }} - name: Remove DigiCert client certificate after signing shell: bash run: | rm -f ${{ env.SM_CLIENT_CERT_FILE }} - name: Code-sign & create Inso CLI installer (macOS only) if: runner.os == 'macOS' run: ./src/scripts/macos-pkg.sh shell: bash working-directory: ./packages/${{ env.INSO_PACKAGE_NAME }} continue-on-error: false env: MACOS_CERTIFICATE: ${{ secrets.DESIGNER_MAC_CSC_LINK }} MACOS_CERTIFICATE_PWD: ${{ secrets.DESIGNER_MAC_CSC_KEY_PASSWORD }} PKG_NAME: inso-${{ matrix.os }}-${{ env.INSO_VERSION }} BUNDLE_ID: com.insomnia.inso VERSION: ${{ env.INSO_VERSION }} - name: Notarize Inso CLI installer (macOS only) if: runner.os == 'macOS' env: APPLE_ID: ${{ secrets.DESIGNER_APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.DESIGNER_APPLE_ID_PASSWORD }} run: | xcrun notarytool submit \ "./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/inso-${{ matrix.os }}-${{ env.INSO_VERSION }}.pkg" \ --apple-id "$APPLE_ID" \ --password "$APPLE_ID_PASSWORD" \ --team-id FX44YY62GV \ --verbose \ --wait - name: Staple Inso CLI installer (macOS only) if: runner.os == 'macOS' run: | xcrun stapler staple \ "./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/inso-${{ matrix.os }}-${{ env.INSO_VERSION }}.pkg" - name: Notarize Inso CLI binary (macOS only) if: runner.os == 'macOS' env: APPLE_ID: ${{ secrets.DESIGNER_APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.DESIGNER_APPLE_ID_PASSWORD }} # notarytool requires the binary to be packaged in a zip, dmg, or pkg. run: | BIN_PATH="./packages/${{ env.INSO_PACKAGE_NAME }}/binaries/inso" ZIP_PATH="$(mktemp -d)/inso.zip" ditto -c -k --keepParent "$BIN_PATH" "$ZIP_PATH" xcrun notarytool submit "$ZIP_PATH" \ --apple-id "$APPLE_ID" \ --password "$APPLE_ID_PASSWORD" \ --team-id FX44YY62GV \ --wait - name: Create Inso zip/tar/gz artifacts run: npm run artifacts -w insomnia-inso - name: Login to Docker Hub if: runner.os == 'Linux' && runner.arch == 'X64' uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ secrets.DOCKER_REGISTRY_USER }} password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} - name: Create inso Docker Image artifacts if: runner.os == 'Linux' && runner.arch == 'X64' run: | DOCKER_BUILDKIT=1 docker build --tag ${{ env.INSO_PACKAGE_NAME }}:temp ./packages/${{ env.INSO_PACKAGE_NAME }} docker save ${{ env.INSO_PACKAGE_NAME }}:temp -o ./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/${{ env.INSO_DOCKER_TAR }} # Produce Docker SBOM for Inso Image # Automatically uploads to workflow assets - name: Scan inso docker artifacts id: sbom_action if: runner.os == 'Linux' && runner.arch == 'X64' uses: Kong/public-shared-actions/security-actions/scan-docker-image@29dd57c7c19389e07390c1c9fe83aef6ff0c424a # v6.1.0 with: asset_prefix: image-inso-${{ runner.os }}-${{ runner.arch }} image: ./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/${{ env.INSO_DOCKER_TAR }} upload-sbom-release-assets: false # No release is publushed yet. Uploads as workflow assets skip_cis_scan: true env: SYFT_SOURCE_NAME: ${{ env.INSO_DOCKER_TAR }} - name: Upload artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: if-no-files-found: ignore name: ${{ runner.os }}-${{ runner.arch }}-artifacts path: | packages/insomnia/dist/*.exe packages/insomnia/dist/*.yml packages/insomnia/dist/squirrel-windows/* packages/insomnia/dist/*.zip packages/insomnia/dist/*.dmg packages/insomnia/dist/*.snap packages/insomnia/dist/*.rpm packages/insomnia/dist/*.deb packages/insomnia/dist/*.AppImage packages/insomnia/dist/*.tar.gz packages/insomnia-inso/artifacts/* - name: Upload source assets for Sentry uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ runner.os }}-${{ runner.arch }}-sentry path: | packages/insomnia/build/**/*.js packages/insomnia/build/**/*.map !packages/insomnia/build/yarn-standalone.js update-pull-request: if: startsWith(github.ref_name, 'release/') timeout-minutes: ${{ fromJSON(vars.GHA_DEFAULT_TIMEOUT) }} needs: build-and-upload-release-artifacts runs-on: ubuntu-24.04 permissions: contents: read pull-requests: write steps: - name: Checkout branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Get release version id: release_version shell: bash run: | echo "version=$(jq .version packages/insomnia/package.json -rj)" >> $GITHUB_OUTPUT echo "branch=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT - name: update-pull-request env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO: ${{ github.repository }} PR_BODY: | # WARNING: Do not merge this PR. Use the "Publish" workflow. ## Publish workflow: When ready to publish, trigger [Publish](https://github.com/${{ github.repository }}/actions/workflows/release-publish.yml) workflow with these variables: - Release version (`version`): `${{ steps.release_version.outputs.version }}` Alternatively, you can trigger the workflow from [GitHub CLI](https://cli.github.com/): ```bash gh workflow run release-publish.yml -f version=${{ steps.release_version.outputs.version }} --repo ${{ github.repository }} ``` > Release notes will be generated automatically based on the commit messages during publish. Remove any unwanted notes manually afterwards. ## Release artifacts: Download release artifacts [here](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
Edit Changelog file... You can update the changelog.md in this branch, run git log to get the latest changes: ```bash git log --no-merges --oneline --pretty=format:'* %s by @%an' --since="" --until="${{ steps.release_version.outputs.branch }}" ```
Conflicts? Merge branch step failed on the publish workflow? Try this... Run locally: ```bash # Make sure git remote is Kong/insomnia... git checkout develop git merge --no-ff release/ # Solve merge conflicts ... # If there's package-lock conflicts, run `npm install` and commit the package-lock changes git push ```
run: | PR_NUMBER=$(gh pr list --repo "$REPO" --base develop --head "$GITHUB_REF_NAME" --state open --json number -q '.[0].number') if [ -z "$PR_NUMBER" ]; then echo "No open PR found from $GITHUB_REF_NAME into develop; skipping body update." exit 0 fi gh pr edit "$PR_NUMBER" --repo "$REPO" --body "$PR_BODY"