chore: release v0.4.1 #18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Kite / Publish release | |
| on: | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| metadata: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| is_release: ${{ steps.release.outputs.is_release }} | |
| release_version: ${{ steps.release.outputs.release_version }} | |
| version_label: ${{ steps.release.outputs.version_label }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ github.sha }} | |
| - id: pull-request | |
| name: Verify release pull request provenance | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const { data: pulls } = await github.rest.repos.listPullRequestsAssociatedWithCommit({ | |
| owner, | |
| repo, | |
| commit_sha: context.sha, | |
| }); | |
| const pull = pulls.find((candidate) => | |
| candidate.base.ref === "main" && | |
| candidate.merged_at !== null && | |
| candidate.merge_commit_sha === context.sha | |
| ); | |
| if (!pull) { | |
| core.setFailed(`${context.sha} is not the merge commit of a reviewed PR into main`); | |
| return; | |
| } | |
| const expectedRepository = `${owner}/${repo}`; | |
| const isReleaseBranch = /^release\/publish\/v\d+\.\d+\.\d+$/.test(pull.head.ref); | |
| const hasReleaseLabel = pull.labels.some((label) => label.name === "release"); | |
| const isTrustedRelease = | |
| isReleaseBranch && | |
| pull.head.repo?.full_name === expectedRepository && | |
| hasReleaseLabel; | |
| core.setOutput("head_ref", pull.head.ref); | |
| core.setOutput("is_trusted_release", String(isTrustedRelease)); | |
| - id: release | |
| name: Classify merge | |
| env: | |
| HEAD_REF: ${{ steps.pull-request.outputs.head_ref }} | |
| IS_TRUSTED_RELEASE: ${{ steps.pull-request.outputs.is_trusted_release }} | |
| run: | | |
| set -euo pipefail | |
| { | |
| echo "is_release=false" | |
| echo "version_label=main" | |
| } >> "$GITHUB_OUTPUT" | |
| if [[ "$HEAD_REF" =~ ^release/publish/v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then | |
| test "$IS_TRUSTED_RELEASE" = true || { | |
| echo "Release PR must originate in $GITHUB_REPOSITORY and carry the release label" | |
| exit 1 | |
| } | |
| version="${BASH_REMATCH[1]}" | |
| package_version=$(node -p "require('./package.json').version") | |
| test "$version" = "$package_version" || { | |
| echo "Release branch v$version does not match package.json $package_version" | |
| exit 1 | |
| } | |
| { | |
| echo "is_release=true" | |
| echo "release_version=v$version" | |
| echo "version_label=v$version" | |
| } >> "$GITHUB_OUTPUT" | |
| fi | |
| build-agent: | |
| if: needs.metadata.outputs.is_release == 'true' | |
| needs: metadata | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| digest: ${{ steps.build.outputs.digest }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ github.sha }} | |
| - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - id: tags | |
| env: | |
| RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }} | |
| run: | | |
| { | |
| echo 'value<<EOF' | |
| echo 'ghcr.io/copilotkit/opentag-agent:main' | |
| echo "ghcr.io/copilotkit/opentag-agent:sha-${{ github.sha }}" | |
| echo "ghcr.io/copilotkit/opentag-agent:$RELEASE_VERSION" | |
| echo "ghcr.io/copilotkit/opentag-agent:${RELEASE_VERSION%.*}" | |
| echo EOF | |
| } >> "$GITHUB_OUTPUT" | |
| - id: build | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: . | |
| file: deployment/docker/agent.Dockerfile | |
| platforms: linux/amd64 | |
| push: true | |
| tags: ${{ steps.tags.outputs.value }} | |
| labels: | | |
| org.opencontainers.image.revision=${{ github.sha }} | |
| org.opencontainers.image.version=${{ needs.metadata.outputs.version_label }} | |
| cache-from: type=gha,scope=agent | |
| cache-to: type=gha,mode=max,scope=agent | |
| build-runtime: | |
| if: needs.metadata.outputs.is_release == 'true' | |
| needs: metadata | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| digest: ${{ steps.build.outputs.digest }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ github.sha }} | |
| - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - id: tags | |
| env: | |
| RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }} | |
| run: | | |
| { | |
| echo 'value<<EOF' | |
| echo 'ghcr.io/copilotkit/opentag-runtime:main' | |
| echo "ghcr.io/copilotkit/opentag-runtime:sha-${{ github.sha }}" | |
| echo "ghcr.io/copilotkit/opentag-runtime:$RELEASE_VERSION" | |
| echo "ghcr.io/copilotkit/opentag-runtime:${RELEASE_VERSION%.*}" | |
| echo EOF | |
| } >> "$GITHUB_OUTPUT" | |
| - id: build | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: . | |
| file: deployment/docker/runtime.Dockerfile | |
| platforms: linux/amd64 | |
| push: true | |
| tags: ${{ steps.tags.outputs.value }} | |
| labels: | | |
| org.opencontainers.image.revision=${{ github.sha }} | |
| org.opencontainers.image.version=${{ needs.metadata.outputs.version_label }} | |
| cache-from: type=gha,scope=runtime | |
| cache-to: type=gha,mode=max,scope=runtime | |
| staging: | |
| if: needs.metadata.outputs.is_release == 'true' | |
| needs: [metadata, build-agent, build-runtime] | |
| permissions: | |
| contents: read | |
| id-token: write | |
| uses: ./.github/workflows/_deploy-kite-environment.yml | |
| with: | |
| agent_image: ghcr.io/copilotkit/opentag-agent@${{ needs.build-agent.outputs.digest }} | |
| environment: staging | |
| github_environment: kite-staging | |
| runtime_image: ghcr.io/copilotkit/opentag-runtime@${{ needs.build-runtime.outputs.digest }} | |
| github-release: | |
| if: needs.metadata.outputs.is_release == 'true' | |
| needs: [metadata, build-agent, build-runtime, staging] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.sha }} | |
| - name: Create release manifest | |
| env: | |
| AGENT_DIGEST: ${{ needs.build-agent.outputs.digest }} | |
| RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }} | |
| RUNTIME_DIGEST: ${{ needs.build-runtime.outputs.digest }} | |
| SOURCE_COMMIT: ${{ github.sha }} | |
| run: | | |
| jq -n \ | |
| --arg version "$RELEASE_VERSION" \ | |
| --arg commit "$SOURCE_COMMIT" \ | |
| --arg agent_digest "$AGENT_DIGEST" \ | |
| --arg runtime_digest "$RUNTIME_DIGEST" \ | |
| '{version:$version,commit:$commit,images:{agent:{repository:"ghcr.io/copilotkit/opentag-agent",digest:$agent_digest,reference:("ghcr.io/copilotkit/opentag-agent@"+$agent_digest)},runtime:{repository:"ghcr.io/copilotkit/opentag-runtime",digest:$runtime_digest,reference:("ghcr.io/copilotkit/opentag-runtime@"+$runtime_digest)}}}' \ | |
| > container-images.json | |
| - name: Create annotated tag idempotently | |
| env: | |
| RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }} | |
| SOURCE_COMMIT: ${{ github.sha }} | |
| run: | | |
| set -euo pipefail | |
| if git rev-parse "$RELEASE_VERSION" >/dev/null 2>&1; then | |
| test "$(git rev-list -n 1 "$RELEASE_VERSION")" = "$SOURCE_COMMIT" | |
| else | |
| git config user.name copilotkit-devops | |
| git config user.email devops@copilotkit.ai | |
| git tag -a "$RELEASE_VERSION" "$SOURCE_COMMIT" -m "Release $RELEASE_VERSION" | |
| git push origin "$RELEASE_VERSION" | |
| fi | |
| - name: Extract this version's release notes | |
| env: | |
| RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }} | |
| run: | | |
| set -euo pipefail | |
| awk -v heading="## $RELEASE_VERSION" ' | |
| $0 == heading { found = 1; next } | |
| found && /^## / { exit } | |
| found { print } | |
| END { if (!found) exit 1 } | |
| ' CHANGELOG.md > "$RUNNER_TEMP/release-notes.md" | |
| test -s "$RUNNER_TEMP/release-notes.md" | |
| - name: Create GitHub Release idempotently | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| RELEASE_VERSION: ${{ needs.metadata.outputs.release_version }} | |
| run: | | |
| set -euo pipefail | |
| if gh release view "$RELEASE_VERSION" >/dev/null 2>&1; then | |
| gh release edit "$RELEASE_VERSION" --title "$RELEASE_VERSION" \ | |
| --notes-file "$RUNNER_TEMP/release-notes.md" | |
| gh release upload "$RELEASE_VERSION" container-images.json --clobber | |
| else | |
| gh release create "$RELEASE_VERSION" container-images.json \ | |
| --title "$RELEASE_VERSION" \ | |
| --notes-file "$RUNNER_TEMP/release-notes.md" --verify-tag | |
| fi | |
| prod: | |
| if: needs.metadata.outputs.is_release == 'true' && needs.github-release.result == 'success' | |
| needs: [metadata, build-agent, build-runtime, github-release] | |
| permissions: | |
| contents: read | |
| id-token: write | |
| uses: ./.github/workflows/_deploy-kite-environment.yml | |
| with: | |
| agent_image: ghcr.io/copilotkit/opentag-agent@${{ needs.build-agent.outputs.digest }} | |
| environment: prod | |
| github_environment: kite-prod | |
| runtime_image: ghcr.io/copilotkit/opentag-runtime@${{ needs.build-runtime.outputs.digest }} | |
| community: | |
| if: needs.metadata.outputs.is_release == 'true' && needs.github-release.result == 'success' | |
| needs: [metadata, build-agent, build-runtime, github-release] | |
| permissions: | |
| contents: read | |
| id-token: write | |
| uses: ./.github/workflows/_deploy-kite-environment.yml | |
| with: | |
| agent_image: ghcr.io/copilotkit/opentag-agent@${{ needs.build-agent.outputs.digest }} | |
| environment: community | |
| github_environment: kite-community | |
| runtime_image: ghcr.io/copilotkit/opentag-runtime@${{ needs.build-runtime.outputs.digest }} |