Skip to content

chore: release v0.4.1 #18

chore: release v0.4.1

chore: release v0.4.1 #18

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 }}