Skip to content

Commit b22e377

Browse files
authored
Add automated OpenAPI spec sync to aap-openapi-specs on merge (#1832)
1 parent 1a425b3 commit b22e377

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
name: Sync OpenAPI Spec to Central Repo
2+
3+
permissions:
4+
contents: read
5+
6+
on:
7+
push:
8+
branches:
9+
- main
10+
- stable-2.6
11+
- stable-2.7
12+
paths:
13+
- 'tools/openapi-schema/**'
14+
- 'ansible_ai_connect/ai/api/**'
15+
- 'ansible_ai_connect/users/**'
16+
- 'ansible_ai_connect/healthcheck/**'
17+
- '.github/workflows/sync-openapi-spec.yml'
18+
workflow_dispatch: # Allow manual triggering
19+
20+
jobs:
21+
generate-and-sync-spec:
22+
# Only run for specific branches
23+
if: contains(fromJSON('["main", "stable-2.6", "stable-2.7"]'), github.ref_name)
24+
name: Generate and sync OpenAPI spec
25+
runs-on: ubuntu-latest
26+
27+
env:
28+
ANSIBLE_AI_DATABASE_HOST: localhost
29+
ANSIBLE_AI_DATABASE_NAME: wisdom
30+
ANSIBLE_AI_DATABASE_PASSWORD: wisdom
31+
ANSIBLE_AI_DATABASE_USER: wisdom
32+
DJANGO_SETTINGS_MODULE: ansible_ai_connect.main.settings.development
33+
ENABLE_ANSIBLE_LINT_POSTPROCESS: True
34+
PYTHONUNBUFFERED: 1
35+
SECRET_KEY: somesecret
36+
37+
services:
38+
postgres:
39+
image: docker.io/library/postgres:alpine
40+
env:
41+
POSTGRES_USER: wisdom
42+
POSTGRES_PASSWORD: wisdom
43+
POSTGRES_DB: wisdom
44+
ports:
45+
- 5432:5432
46+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
47+
48+
steps:
49+
- name: Checkout repository
50+
uses: actions/checkout@v4
51+
52+
- name: Determine target branch in spec repo
53+
id: branch_mapping
54+
run: |
55+
SOURCE_BRANCH="${{ github.ref_name }}"
56+
57+
# Map source branch to target branch in spec repo
58+
case "$SOURCE_BRANCH" in
59+
"main")
60+
TARGET_BRANCH="devel"
61+
;;
62+
"stable-2.6")
63+
TARGET_BRANCH="stable-2.6"
64+
;;
65+
"stable-2.7")
66+
TARGET_BRANCH="stable-2.7"
67+
;;
68+
*)
69+
TARGET_BRANCH="devel"
70+
;;
71+
esac
72+
73+
echo "source_branch=$SOURCE_BRANCH" >> $GITHUB_OUTPUT
74+
echo "target_branch=$TARGET_BRANCH" >> $GITHUB_OUTPUT
75+
echo "πŸ“ Source branch: $SOURCE_BRANCH β†’ Target branch: $TARGET_BRANCH"
76+
77+
- name: Setup Python 3.12
78+
uses: actions/setup-python@v4
79+
with:
80+
python-version: '3.12'
81+
82+
- name: Install Dependencies
83+
run: |
84+
python3 -m pip install --upgrade pip
85+
pip install -r requirements.txt
86+
pip install .[dev]
87+
88+
- name: Create CA symlink to use RH's certifi on ubuntu-latest
89+
run: |
90+
sudo mkdir -p /etc/pki/tls/certs
91+
sudo ln -s /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt
92+
93+
- name: Start Django server and generate OpenAPI spec
94+
run: |
95+
make run-server &
96+
sleep 10
97+
make create-cachetable
98+
make update-openapi-schema
99+
100+
- name: Verify spec file exists
101+
run: |
102+
SPEC_FILE="./tools/openapi-schema/ansible-ai-connect-service.json"
103+
if [ ! -f "$SPEC_FILE" ]; then
104+
echo "❌ Spec file not found at $SPEC_FILE"
105+
ls -la ./tools/openapi-schema/
106+
exit 1
107+
fi
108+
echo "βœ… Found spec file at $SPEC_FILE"
109+
110+
- name: Checkout spec repo
111+
uses: actions/checkout@v4
112+
with:
113+
repository: ansible-automation-platform/aap-openapi-specs
114+
ref: ${{ steps.branch_mapping.outputs.target_branch }}
115+
path: spec-repo
116+
token: ${{ secrets.OPENAPI_SPEC_SYNC_TOKEN }}
117+
118+
- name: Check if branch exists in spec repo
119+
id: check_branch
120+
working-directory: spec-repo
121+
run: |
122+
BRANCH="${{ steps.branch_mapping.outputs.target_branch }}"
123+
124+
# Check if branch exists locally (already checked out)
125+
if git rev-parse --verify HEAD >/dev/null 2>&1; then
126+
echo "βœ… Branch '$BRANCH' exists in spec repo"
127+
echo "branch_exists=true" >> $GITHUB_OUTPUT
128+
else
129+
echo "❌ Branch '$BRANCH' does NOT exist in spec repo"
130+
echo "branch_exists=false" >> $GITHUB_OUTPUT
131+
fi
132+
133+
- name: Fail if branch doesn't exist
134+
if: steps.check_branch.outputs.branch_exists != 'true'
135+
run: |
136+
echo "##[error]❌ Branch '${{ steps.branch_mapping.outputs.target_branch }}' does not exist in the central spec repository."
137+
echo "##[error]Expected branch: ${{ steps.branch_mapping.outputs.target_branch }}"
138+
echo "##[error]This branch must be created in the spec repo before specs can be synced."
139+
exit 1
140+
141+
- name: Compare specs
142+
id: compare
143+
run: |
144+
COMPONENT_SPEC="./tools/openapi-schema/ansible-ai-connect-service.json"
145+
SPEC_REPO_FILE="spec-repo/lightspeed.json"
146+
147+
# Check if spec file exists in spec repo
148+
if [ ! -f "$SPEC_REPO_FILE" ]; then
149+
echo "Spec file doesn't exist in spec repo - will create new file"
150+
echo "has_diff=true" >> $GITHUB_OUTPUT
151+
echo "is_new_file=true" >> $GITHUB_OUTPUT
152+
else
153+
# Compare files
154+
if diff -q "$COMPONENT_SPEC" "$SPEC_REPO_FILE" > /dev/null; then
155+
echo "βœ… No differences found - specs are identical"
156+
echo "has_diff=false" >> $GITHUB_OUTPUT
157+
else
158+
echo "πŸ“ Differences found - spec has changed"
159+
echo "has_diff=true" >> $GITHUB_OUTPUT
160+
echo "is_new_file=false" >> $GITHUB_OUTPUT
161+
fi
162+
fi
163+
164+
- name: Update spec file
165+
if: steps.compare.outputs.has_diff == 'true'
166+
run: |
167+
cp "./tools/openapi-schema/ansible-ai-connect-service.json" "spec-repo/lightspeed.json"
168+
echo "βœ… Updated spec-repo/lightspeed.json"
169+
170+
- name: Create PR in spec repo
171+
if: steps.compare.outputs.has_diff == 'true'
172+
working-directory: spec-repo
173+
env:
174+
GH_TOKEN: ${{ secrets.OPENAPI_SPEC_SYNC_TOKEN }}
175+
run: |
176+
# Configure git
177+
git config user.name "github-actions[bot]"
178+
git config user.email "github-actions[bot]@users.noreply.github.com"
179+
180+
# Create branch for PR
181+
SHORT_SHA="${{ github.sha }}"
182+
SHORT_SHA="${SHORT_SHA:0:7}"
183+
BRANCH_NAME="update-lightspeed-${{ github.ref_name }}-${SHORT_SHA}"
184+
git checkout -b "$BRANCH_NAME"
185+
186+
# Add and commit changes
187+
git add "lightspeed.json"
188+
189+
if [ "${{ steps.compare.outputs.is_new_file }}" == "true" ]; then
190+
COMMIT_MSG="Add Lightspeed OpenAPI spec for ${{ github.ref_name }}"
191+
else
192+
COMMIT_MSG="Update Lightspeed OpenAPI spec for ${{ github.ref_name }}"
193+
fi
194+
195+
git commit -m "$COMMIT_MSG
196+
197+
Synced from ${{ github.repository }}@${{ github.sha }}
198+
Source branch: ${{ github.ref_name }}
199+
200+
Co-Authored-By: github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
201+
202+
# Push branch
203+
git push origin "$BRANCH_NAME"
204+
205+
# Create PR
206+
PR_TITLE="[${{ github.ref_name }}] Update Lightspeed spec from merged commit"
207+
208+
# Get commit message
209+
COMMIT_MSG="${{ github.event.head_commit.message }}"
210+
if [ -z "$COMMIT_MSG" ]; then
211+
COMMIT_MSG="Manual workflow trigger or commit message unavailable"
212+
fi
213+
214+
PR_BODY="## Summary
215+
Automated OpenAPI spec sync from component repository merge.
216+
217+
**Source:** [${{ github.repository }}@\`${SHORT_SHA}\`](https://github.com/${{ github.repository }}/commit/${{ github.sha }})
218+
**Branch:** \`${{ github.ref_name }}\`
219+
**Component:** \`lightspeed\`
220+
**Spec File:** \`lightspeed.json\`
221+
222+
## Changes
223+
$(if [ "${{ steps.compare.outputs.is_new_file }}" == "true" ]; then echo "- πŸ†• New spec file created"; else echo "- πŸ“ Spec file updated with latest changes"; fi)
224+
225+
## Source Commit
226+
\`\`\`
227+
${COMMIT_MSG}
228+
\`\`\`
229+
230+
---
231+
πŸ€– This PR was automatically generated by the OpenAPI spec sync workflow."
232+
233+
gh pr create \
234+
--title "$PR_TITLE" \
235+
--body "$PR_BODY" \
236+
--base "${{ steps.branch_mapping.outputs.target_branch }}" \
237+
--head "$BRANCH_NAME"
238+
239+
echo "βœ… Created PR in spec repo"
240+
241+
- name: Report results
242+
if: always()
243+
run: |
244+
if [ "${{ steps.compare.outputs.has_diff }}" == "true" ]; then
245+
echo "πŸ“ Spec sync completed - PR created in spec repo"
246+
else
247+
echo "βœ… Spec sync completed - no changes needed"
248+
fi

0 commit comments

Comments
Β (0)