Skip to content

[OPIK-5722] [BE] [FE] [SDK] Fix config version selection in Agent San… #413

[OPIK-5722] [BE] [FE] [SDK] Fix config version selection in Agent San…

[OPIK-5722] [BE] [FE] [SDK] Fix config version selection in Agent San… #413

name: SDKs Generate OpenAPI spec and Fern code
on:
push:
branches: ['main']
paths:
- 'apps/opik-backend/src/main/java/**/*.java'
- 'apps/opik-backend/src/main/resources/openapi_template.yml'
- 'apps/opik-backend/pom.xml'
workflow_dispatch: # Allows manual trigger
concurrency:
group: fern-auto-update
cancel-in-progress: true
jobs:
resolve-trigger-context:
runs-on: ubuntu-latest
if: github.event_name == 'push'
permissions:
contents: read
outputs:
trigger_author: ${{ steps.get-author.outputs.author }}
originating_pr_url: ${{ steps.find-pr.outputs.pr_url }}
steps:
- name: Get merge author
id: get-author
run: |
AUTHOR="${{ github.event.head_commit.author.username }}"
if [ -z "$AUTHOR" ]; then
AUTHOR="${{ github.actor }}"
fi
echo "author=$AUTHOR" >> $GITHUB_OUTPUT
- name: Find originating PR
id: find-pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_URL=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" --jq '.[0].html_url' 2>/dev/null || echo "")
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
update-open-api-spec-and-fern-code:
needs: resolve-trigger-context
if: ${{ !failure() }}
runs-on: ubuntu-latest
permissions:
contents: write
timeout-minutes: 15
outputs:
pr_url: ${{ steps.create-pr.outputs.pull-request-url }}
pr_number: ${{ steps.create-pr.outputs.pull-request-number }}
steps:
- name: Checkout Repository
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'corretto'
cache: maven
- name: Install Fern
run: npm install -g fern-api
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install Opik Optimizer SDK (for Fern docs)
run: |
python -m pip install --upgrade pip
pip install -e sdks/opik_optimizer
- name: Set branch name
run: |
echo "BRANCH_NAME=github-actions/NA-automatically-update-openapi-spec-and-fern-code-$(date +%Y-%m-%d-%H-%M-%S)" >> $GITHUB_ENV
- name: Run Generate OpenAPI spec and Fern code
env:
FERN_TOKEN: ${{ secrets.FERN_TOKEN }}
run: |
set -e
cd apps/opik-backend
mvn clean
cd -
./scripts/generate_openapi.sh
- name: Generate Opik Optimizer Fern docs
run: |
python sdks/opik_optimizer/scripts/generate_fern_docs.py --write
- name: Prepare PR context
id: pr-context
run: |
if [ "${{ github.event_name }}" == "push" ]; then
ORIGINATING_PR="${{ needs.resolve-trigger-context.outputs.originating_pr_url }}"
if [ -n "$ORIGINATING_PR" ]; then
echo "trigger_info=**Triggered by BE merge:** $ORIGINATING_PR" >> $GITHUB_OUTPUT
else
echo "trigger_info=**Triggered by commit:** https://github.com/${{ github.repository }}/commit/${{ github.sha }}" >> $GITHUB_OUTPUT
fi
else
echo "trigger_info=" >> $GITHUB_OUTPUT
fi
- name: Check for changes
id: check_changes
run: |
if git diff --quiet; then
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "has_changes=true" >> $GITHUB_OUTPUT
fi
- name: Commit files
if: steps.check_changes.outputs.has_changes == 'true'
run: |
set -ex
git config --local user.email "github-actions@comet.com"
git config --local user.name "Github Actions (${{ github.actor }})"
git add sdks/python/src/opik/rest_api/
git add sdks/typescript/src/opik/rest_api/
git add sdks/code_generation/fern/openapi/openapi.yaml
git add apps/opik-documentation/documentation/fern/openapi/opik.yaml
git add apps/opik-documentation/documentation/fern/docs/agent_optimization/opik_optimizer/reference.mdx
git commit -m "[NA] [SDK] [DOCS] Update automatically OpenAPI spec and Fern code"
- name: Create Pull Request
if: steps.check_changes.outputs.has_changes == 'true'
id: create-pr
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.COMET_ACTION_CREATE_PR }}
branch: ${{ env.BRANCH_NAME }}
title: "[NA] [SDK] [DOCS] Update automatically OpenAPI spec and Fern code"
body: |
## Details
Automated update of OpenAPI spec and Fern code after running `./scripts/generate_openapi.sh` and `./sdks/opik_optimizer/scripts/generate_fern_docs.py`.
${{ steps.pr-context.outputs.trigger_info }}
## Change checklist
- [ ] User facing changes
- [X] Documentation updated
## Issues
N/A
## Testing
- Passed CI
## Documentation
- https://buildwithfern.com/learn/cli-api-reference/cli-reference/commands#fern-generate
base: main
notify-slack:
name: Notify #code-review
runs-on: ubuntu-latest
permissions: {}
needs: [update-open-api-spec-and-fern-code, resolve-trigger-context]
if: >-
!failure() &&
github.event_name == 'push' &&
needs.update-open-api-spec-and-fern-code.outputs.pr_url != ''
steps:
- name: Check Slack configuration
id: check-slack
run: |
if [ -z "${{ secrets.SLACK_WEBHOOK_URL_CODE_REVIEW }}" ]; then
echo "configured=false" >> $GITHUB_OUTPUT
echo "SLACK_WEBHOOK_URL_CODE_REVIEW not configured — skipping notification"
else
echo "configured=true" >> $GITHUB_OUTPUT
fi
- name: Resolve Slack mention
id: resolve-mention
if: steps.check-slack.outputs.configured == 'true'
env:
SLACK_USER_MAPPING: ${{ secrets.SLACK_USER_MAPPING }}
run: |
AUTHOR="${{ needs.resolve-trigger-context.outputs.trigger_author }}"
AUTHOR_MENTION=""
if [ -n "$SLACK_USER_MAPPING" ] && [ -n "$AUTHOR" ]; then
AUTHOR_SLACK_ID=$(echo "$SLACK_USER_MAPPING" | jq -r --arg user "$AUTHOR" '.[$user] // empty' 2>/dev/null || echo "")
if [ -n "$AUTHOR_SLACK_ID" ]; then
AUTHOR_MENTION="<@$AUTHOR_SLACK_ID>"
fi
fi
echo "mention=$AUTHOR_MENTION" >> $GITHUB_OUTPUT
echo "author_display=$AUTHOR" >> $GITHUB_OUTPUT
- name: Send Slack notification
if: steps.check-slack.outputs.configured == 'true'
env:
SLACK_WEBHOOK_URL_CODE_REVIEW: ${{ secrets.SLACK_WEBHOOK_URL_CODE_REVIEW }}
run: |
PR_URL="${{ needs.update-open-api-spec-and-fern-code.outputs.pr_url }}"
PR_NUMBER="${{ needs.update-open-api-spec-and-fern-code.outputs.pr_number }}"
ORIGINATING_PR="${{ needs.resolve-trigger-context.outputs.originating_pr_url }}"
AUTHOR="${{ steps.resolve-mention.outputs.author_display }}"
MENTION="${{ steps.resolve-mention.outputs.mention }}"
COMMIT_SHA="${{ github.sha }}"
SHORT_SHA="${COMMIT_SHA:0:7}"
# Build trigger text
if [ -n "$ORIGINATING_PR" ]; then
TRIGGER_TEXT="*Triggered by:*\n<$ORIGINATING_PR|BE PR> by $AUTHOR"
else
TRIGGER_TEXT="*Triggered by:*\nCommit <https://github.com/${{ github.repository }}/commit/$COMMIT_SHA|\`$SHORT_SHA\`> by $AUTHOR"
fi
# Build mention text
MENTION_TEXT=""
if [ -n "$MENTION" ]; then
MENTION_TEXT="$MENTION Your BE merge triggered FERN changes. Please review."
fi
# Build JSON payload with jq to handle special characters safely
jq -n \
--arg pr_url "$PR_URL" \
--arg pr_num "$PR_NUMBER" \
--arg trigger "$TRIGGER_TEXT" \
--arg mention "$MENTION_TEXT" \
'
{
"attachments": [{
"color": "#36a64f",
"blocks": (
[
{"type": "header", "text": {"type": "plain_text", "text": "FERN Update PR \u2014 Review Needed", "emoji": true}},
{"type": "section", "text": {"type": "mrkdwn", "text": "A BE merge to main changed the OpenAPI spec. FERN SDK code has been regenerated."}},
{"type": "section", "fields": [
{"type": "mrkdwn", "text": ("*FERN PR:*\n<" + $pr_url + "|#" + $pr_num + ">")},
{"type": "mrkdwn", "text": $trigger}
]}
]
+ (if $mention != "" then [{"type": "section", "text": {"type": "mrkdwn", "text": $mention}}] else [] end)
+ [
{"type": "actions", "elements": [{
"type": "button",
"text": {"type": "plain_text", "text": "Review FERN PR", "emoji": true},
"url": $pr_url,
"style": "primary"
}]}
]
)
}]
}
' > payload.json
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST \
-H 'Content-type: application/json' \
--data @payload.json \
"$SLACK_WEBHOOK_URL_CODE_REVIEW")
if [ "$HTTP_CODE" -eq 200 ]; then
echo "Slack notification sent successfully"
else
echo "Slack notification failed with HTTP code: $HTTP_CODE"
exit 1
fi