name: Release Publish run-name: Publish ${{ github.event.inputs.version }} channel by @${{ github.actor }} on: workflow_dispatch: inputs: release_build: required: true type: boolean default: false description: Confirm that release-build.yml has been triggered for this version version: required: true description: Release version (e.g. 12.5.0) env: RELEASE_VERSION: ${{ github.event.inputs.version }} RELEASE_CORE_TAG: core@${{ github.event.inputs.version }} RELEASE_BRANCH: release/${{ github.event.inputs.version }} IS_PRERELEASE: ${{ contains(github.event.inputs.version, 'alpha') || contains(github.event.inputs.version, 'beta') }} ARTIFACTS_DOWNLOAD_PATH: ${{ github.workspace }}/artifacts ARTIFACTS_VERIFY_DOWNLOAD_PATH: ${{ github.workspace }}/artifacts_verify INSO_DOCKER_IMAGE: &INSO_DOCKER_IMAGE 'kong/inso' # By default, registry is docker.io NOTARY_REPOSITORY: &NOTARY_REPOSITORY 'kong/notary' # All signatures will be pushed to public notary repository permissions: {} jobs: publish: timeout-minutes: 30 runs-on: ubuntu-24.04 outputs: NOTARY_REPOSITORY: ${{ env.NOTARY_REPOSITORY }} INSO_BINARY_ARTIFACTS_SUBJECTS_AS_FILE: ${{ steps.cli_binary_hashes.outputs.handle }} INSO_DOCKER_IMAGE: ${{ env.INSO_DOCKER_IMAGE }} INSO_DOCKER_IMAGE_DIGEST: ${{ steps.image_manifest_metadata.outputs.inso_image_sha }} INSOMNIA_RELEASE_TAG: ${{ env.RELEASE_CORE_TAG }} ELECTRON_BINARY_ARTIFACTS_SUBJECTS_AS_FILE: ${{ steps.electron_binary_hashes.outputs.handle }} permissions: id-token: write # needed for signing the images actions: read # For getting workflow run info for keyless signing of docker image contents: write # Required to upload assets. Issue: https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/container#known-issues packages: write steps: - name: Harden Runner uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Check Release Build Confirmed env: IS_RELEASE_BUILD_TRIGGERED: ${{ github.event.inputs.release_build }} run: | if [ "$IS_RELEASE_BUILD_TRIGGERED" != "true" ]; then echo "::error title=Missing Release Build::You must check 'release_build' to confirm that release-build.yml has been triggered for this version before running this workflow." exit 1 fi - name: Calculate Release Branch env: VERSION: ${{ github.event.inputs.version }} run: | MAJOR_MINOR=$(echo "$VERSION" | cut -d. -f1,2) # Rewrite the release branch to follow our new flow echo "RELEASE_BRANCH=release/$MAJOR_MINOR" >> $GITHUB_ENV - name: Checkout branch # Check out the release branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ env.RELEASE_BRANCH }} fetch-depth: 0 persist-credentials: false - 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: Compare input version with package.json version env: VERSION: ${{ github.event.inputs.version }} run: | PKG_VERSION=$(jq .version packages/insomnia-inso/package.json -rj) if [ "$PKG_VERSION" != "$VERSION" ]; then echo "Input version $VERSION does not match package.json version $PKG_VERSION" exit 1 fi - name: Download all artifacts from release-build.yml uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20 with: github_token: ${{secrets.GITHUB_TOKEN}} workflow: release-build.yml workflow_conclusion: success branch: ${{ env.RELEASE_BRANCH }} # Branch workflow ran on != branch the workflow created path: ${{ env.ARTIFACTS_DOWNLOAD_PATH }} # Base path to download all release workflow assets - name: Set publish metadata # Checksum for provenance must be calculated before moving artifacts temporarily id: metadata run: | INSO_VERSION=$(jq .version packages/insomnia-inso/package.json -rj) echo "INSO_VERSION=${INSO_VERSION}" >> $GITHUB_ENV echo "CLI_ARTIFACT_BASE64_FILE=${{env.CLI_ARTIFACT_BASE64_FILE}}" >> $GITHUB_ENV echo "ELECTRON_ARTIFACT_BASE64_FILE=${{env.ELECTRON_ARTIFACT_BASE64_FILE}}" >> $GITHUB_ENV ./.github/scripts/generate-binary-digest.sh env: ARTIFACT_PATH: '${{ env.ARTIFACTS_DOWNLOAD_PATH }}' CLI_ARTIFACT_SHAFILE: ${{runner.temp}}/cli.sha256 ELECTRON_ARTIFACT_SHAFILE: ${{runner.temp}}/electron.sha256 CLI_ARTIFACT_BASE64_FILE: ${{runner.temp}}/cli_digests_file.text ELECTRON_ARTIFACT_BASE64_FILE: ${{runner.temp}}/electron_digests_file.text - name: Calculate CLI Binary base64 file handle uses: slsa-framework/slsa-github-generator/actions/generator/generic/create-base64-subjects-from-file@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0 id: cli_binary_hashes with: path: ${{ env.CLI_ARTIFACT_BASE64_FILE }} - name: Calculate Electron Binary base64 file handle uses: slsa-framework/slsa-github-generator/actions/generator/generic/create-base64-subjects-from-file@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0 id: electron_binary_hashes with: path: ${{ env.ELECTRON_ARTIFACT_BASE64_FILE }} - name: Determine previous release tag id: previous_tag run: | PREVIOUS_TAG=$(node ./.github/scripts/resolve-previous-release-tag.js "${RELEASE_CORE_TAG}") echo "Resolved previous tag for changelog diff: ${PREVIOUS_TAG:-}" echo "PREVIOUS_TAG=${PREVIOUS_TAG}" >> "$GITHUB_ENV" - name: Create Tag and Release uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0 id: core_tag_and_release with: tag: ${{ env.RELEASE_CORE_TAG }} name: '${{ env.RELEASE_VERSION }} 📦' generateReleaseNotes: true generateReleaseNotesPreviousTag: ${{ env.PREVIOUS_TAG }} commit: ${{ env.RELEASE_BRANCH }} prerelease: ${{ env.IS_PRERELEASE }} draft: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload artifacts to release uses: xresloader/upload-to-github-release@7c5757a90c0bcf0c0e1741da8f2abd7b85e675d0 # v1.6.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: release_id: ${{ steps.core_tag_and_release.outputs.id }} tag_name: ${{ env.RELEASE_CORE_TAG }} file: './artifacts/*-artifacts/insomnia/dist/Insomnia.*;./artifacts/*-artifacts/insomnia/dist/{alpha,beta,latest}.yml;./artifacts/*-artifacts/insomnia/dist/squirrel-windows/*;./artifacts/*-artifacts/insomnia-inso/artifacts/inso-*;./artifacts/**/*sbom.{spdx,cyclonedx}.json' prerelease: ${{ env.IS_PRERELEASE }} draft: false overwrite: true - name: Upload sourcemaps to Sentry env: SENTRY_AUTH_TOKEN: '${{ secrets.SENTRY_AUTH_TOKEN }}' SENTRY_ORG: '${{ secrets.SENTRY_ORG }}' SENTRY_PROJECT: '${{ secrets.SENTRY_PROJECT }}' run: | curl -sL https://sentry.io/get-cli/ | SENTRY_CLI_VERSION="2.2.0" bash sentry-cli releases new ${{ env.RELEASE_VERSION }} sentry-cli releases set-commits ${{ env.RELEASE_VERSION }} --commit 'Kong/insomnia@${{ env.RELEASE_BRANCH }}' sentry-cli sourcemaps upload -r ${{ env.RELEASE_VERSION }} ./artifacts/macOS-X64-sentry # TODO: also take care of aarch64 image - name: Load the Inso CLI Docker Archive run: | docker load -i ./artifacts/Linux-X64-artifacts/insomnia-inso/artifacts/inso-docker-image.tar docker image ls - name: Login to Docker Hub uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ secrets.DOCKER_REGISTRY_USER }} password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} - name: Docker meta for Inso CLI Docker Image id: inso_docker_meta uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 with: images: ${{ env.INSO_DOCKER_IMAGE }} tags: | type=raw,value=${{ env.RELEASE_VERSION }},priority=1000 type=raw,value=latest,enable=${{ env.IS_PRERELEASE == 'false' }} type=raw,value=alpha,enable=${{ env.IS_PRERELEASE == 'true' && contains(github.event.inputs.version, 'alpha') }} type=raw,value=beta,enable=${{ env.IS_PRERELEASE == 'true' && contains(github.event.inputs.version, 'beta') }} sep-tags: ',' - name: Push Inso CLI docker image tags to Docker Hub run: | for tag in ${IMAGE_TAGS//,/ }; do \ docker tag insomnia-inso:temp $tag docker push $tag; \ done env: IMAGE_TAGS: ${{ steps.inso_docker_meta.outputs.tags }} # Setup regctl to parse platform specific image digest from image manifest - name: Install regctl uses: regclient/actions/regctl-installer@ce5fd131e371ffcdd7508b478cb223b3511a9183 # main # The image manifest digest/sha is generated only after the image is published to registry - name: Parse architecture specific digest from image manifest id: image_manifest_metadata run: | INSO_IMAGE=${{ env.INSO_DOCKER_IMAGE }}:${{ steps.inso_docker_meta.outputs.version }} inso_image_sha="$(regctl image digest "${INSO_IMAGE}")" echo "inso_image_sha=${inso_image_sha}" >> $GITHUB_OUTPUT # Signing images requires image manifest digest - name: Sign images id: sign_images if: ${{ steps.image_manifest_metadata.outputs.inso_image_sha != '' }} uses: Kong/public-shared-actions/security-actions/sign-docker-image@2f02738ecb1670f01391162e43fe3f5d4e7942a1 # v2.2.2 with: image_digest: ${{ steps.image_manifest_metadata.outputs.inso_image_sha }} tags: ${{ steps.inso_docker_meta.outputs.tags }} registry_username: ${{ secrets.DOCKER_REGISTRY_USER }} registry_password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} # Optional: Central notary repository for image signatures signature_registry_username: ${{ secrets.DOCKER_REGISTRY_USER }} signature_registry_password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} signature_registry: ${{ env.NOTARY_REPOSITORY }} - name: Publish beta/stable of Insomnia to Insomnia API if: ${{ !contains(github.event.inputs.version, 'alpha') }} run: | curl \ --fail \ --request POST \ --url $INSOMNIA_API_URL/v1/releases \ --header "Authorization: Bearer ${INSOMNIA_API_TOKEN}" \ --header "Content-Type: application/json" \ --data "{ \"app\": \"${RELEASE_APP}\", \"version\": \"${RELEASE_VERSION}\", \"channel\": \"${RELEASE_CHANNEL}\", \"release_date\": \"$(date --rfc-3339=ns | sed 's/ /T/; s/\(\....\).*\([+-]\)/\1\2/g')\" }" env: INSOMNIA_API_URL: ${{ secrets.INSOMNIA_API_URL }} INSOMNIA_API_TOKEN: ${{ secrets.INSOMNIA_API_TOKEN }} RELEASE_APP: com.insomnia.app RELEASE_VERSION: ${{ env.RELEASE_VERSION }} RELEASE_CHANNEL: ${{ contains(github.event.inputs.version, 'beta') && 'beta' || 'stable' }} - name: Publish beta/stable of inso to Insomnia API if: ${{ !contains(github.event.inputs.version, 'alpha') }} run: | curl \ --fail \ --request POST \ --url $INSOMNIA_API_URL/v1/releases \ --header "Authorization: Bearer ${INSOMNIA_API_TOKEN}" \ --header "Content-Type: application/json" \ --data "{ \"app\": \"${RELEASE_APP}\", \"version\": \"${RELEASE_VERSION}\", \"channel\": \"${RELEASE_CHANNEL}\", \"release_date\": \"$(date --rfc-3339=ns | sed 's/ /T/; s/\(\....\).*\([+-]\)/\1\2/g')\" }" env: INSOMNIA_API_URL: ${{ secrets.INSOMNIA_API_URL }} INSOMNIA_API_TOKEN: ${{ secrets.INSOMNIA_API_TOKEN }} RELEASE_APP: com.insomnia.inso RELEASE_VERSION: ${{ env.RELEASE_VERSION }} RELEASE_CHANNEL: ${{ contains(github.event.inputs.version, 'beta') && 'beta' || 'stable' }} - name: Upload x64 Linux snap to snapcraft (beta and stable only) if: ${{ !contains(github.event.inputs.version, 'alpha') }} env: SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_LOGIN_FILE_NEW }} SNAP_CHANNEL: ${{ contains(github.event.inputs.version, 'beta') && 'beta' || 'stable' }} # TODO-ARM64: Replace to *-amd64.snap when we have ARM64 build from insomnia-ee run: | sudo snap install snapcraft --classic snapcraft upload \ --release="$SNAP_CHANNEL" \ "artifacts/Linux-X64-artifacts/insomnia/dist/Insomnia.Core-${{ env.RELEASE_VERSION }}.snap" - name: Get Cloudsmith OIDC token if: ${{ !contains(github.event.inputs.version, 'alpha') && !contains(github.event.inputs.version, 'beta') }} id: cloudsmith_token uses: cloudsmith-io/cloudsmith-cli-action@18665afcce9f859312b61989671af9af7402e4fb # v2.0.2 with: oidc-namespace: ${{ vars.CLOUDSMITH_NAMESPACE }} oidc-service-slug: ${{ secrets.CLOUDSMITH_SERVICE_SLUG }} oidc-auth-only: true # TODO: also release for aarch64 Linux? - name: Upload .deb to pulp and/or cloudsmith (stable only) if: ${{ !contains(github.event.inputs.version, 'alpha') && !contains(github.event.inputs.version, 'beta') }} uses: docker://kong/release-script@sha256:112bd255bb38be52bd626e7f615fd1c4bb1c948f48612984591907dc7cf95ce4 # 1.36.0 env: PULP_USERNAME: ${{ secrets.PULP_USERNAME }} PULP_PASSWORD: ${{ secrets.PULP_PASSWORD }} PULP_HOST: ${{ secrets.PULP_HOST }} VERBOSE: ${{ runner.debug == '1' && '1' || '' }} CLOUDSMITH_API_KEY: ${{ steps.cloudsmith_token.outputs.oidc-token }} CLOUDSMITH_DRY_RUN: '' IGNORE_CLOUDSMITH_FAILURES: ${{ vars.IGNORE_CLOUDSMITH_FAILURES }} USE_CLOUDSMITH: ${{ vars.USE_CLOUDSMITH }} USE_PULP: ${{ vars.USE_PULP }} with: entrypoint: /entrypoint.sh # TODO-ARM64: Replace to *-amd64.deb when we have arm64 builds from insomnia-ee args: > release --file artifacts/Linux-X64-artifacts/insomnia/dist/Insomnia.Core-${{ env.RELEASE_VERSION }}.deb --dist-name ubuntu --dist-version focal --package-type insomnia ${{ env.IS_PRERELEASE == 'true' && '--internal' || '--publish' }} artifact-provenance: needs: [publish] permissions: id-token: write # needed for signing the images actions: read # For getting workflow run info to build provenance packages: write # Required for publishing provenance. Issue: https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/container#known-issues contents: write strategy: fail-fast: true matrix: include: - product: insomnia binary_artifacts_subject_as_file: ${{ needs.publish.outputs.ELECTRON_BINARY_ARTIFACTS_SUBJECTS_AS_FILE }} - product: inso binary_artifacts_subject_as_file: ${{ needs.publish.outputs.INSO_BINARY_ARTIFACTS_SUBJECTS_AS_FILE }} # need to use non hash version because of: https://github.com/slsa-framework/slsa-github-generator/issues/3498 uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 with: base64-subjects-as-file: '${{ matrix.binary_artifacts_subject_as_file }}' upload-assets: true upload-tag-name: ${{ needs.publish.outputs.INSOMNIA_RELEASE_TAG }} provenance-name: ${{ matrix.product }}-provenance.intoto.jsonl draft-release: false inso-image-provenance: needs: [publish] permissions: id-token: write # needed for signing the images actions: read # For getting workflow run info to build provenance packages: write # Required for publishing provenance. Issue: https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/container#known-issues # need to use non hash version because of: https://github.com/slsa-framework/slsa-github-generator/issues/3498 contents: write uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 with: image: *INSO_DOCKER_IMAGE digest: ${{ needs.publish.outputs.INSO_DOCKER_IMAGE_DIGEST }} provenance-repository: *NOTARY_REPOSITORY secrets: registry-username: ${{ secrets.DOCKER_REGISTRY_USER }} registry-password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} provenance-registry-username: ${{ secrets.DOCKER_REGISTRY_USER }} provenance-registry-password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}