Sync OpenAPI Specs #186
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
| # Sync OpenAPI Specifications and Update Navigation | |
| # | |
| # This workflow runs in the destination repo (DomoApps/domo-developer-portal). | |
| # It syncs OpenAPI YAML files from the source repo and updates docs.json navigation, | |
| # creating a single PR with all changes for review. | |
| name: Sync OpenAPI Specs | |
| # ============================================================================ | |
| # CONFIGURATION - Update these values for your setup | |
| # ============================================================================ | |
| env: | |
| # Source repository (where OpenAPI YAMLs live) | |
| SOURCE_OWNER: domoinc | |
| SOURCE_REPO: internal-domo-apis | |
| SOURCE_YAML_PATH: api-docs/public | |
| # Destination paths (in this repo) | |
| DEST_YAML_PATH: openapi/product | |
| DOCS_JSON_PATH: ./docs.json | |
| OPENAPI_BASE_PATH: openapi/product | |
| # Git settings | |
| BASE_BRANCH: master | |
| # ============================================================================ | |
| on: | |
| schedule: | |
| - cron: "0 */6 * * *" # Every 6 hours | |
| workflow_dispatch: | |
| inputs: | |
| force_sync: | |
| description: "Force sync all YAML files" | |
| required: false | |
| type: boolean | |
| default: false | |
| repository_dispatch: | |
| types: [openapi-updated] | |
| jobs: | |
| sync: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| # Token for source repo (cross-org) | |
| - name: Generate Source Repo Token | |
| uses: actions/create-github-app-token@v1 | |
| id: source-token | |
| with: | |
| app-id: ${{ secrets.APP_ID }} | |
| private-key: ${{ secrets.APP_PRIVATE_KEY }} | |
| owner: ${{ env.SOURCE_OWNER }} | |
| repositories: ${{ env.SOURCE_REPO }} | |
| # Token for destination repo (PRs) | |
| - name: Generate Destination Repo Token | |
| uses: actions/create-github-app-token@v1 | |
| id: dest-token | |
| with: | |
| app-id: ${{ secrets.APP_ID }} | |
| private-key: ${{ secrets.APP_PRIVATE_KEY }} | |
| # No owner specified = current repo's org | |
| - name: Checkout Destination Repo | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Clone Source Repo | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ env.SOURCE_OWNER }}/${{ env.SOURCE_REPO }} | |
| token: ${{ steps.source-token.outputs.token }} | |
| path: source-repo | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: "3.10" | |
| - name: Detect Changed YAML Files | |
| id: detect | |
| run: | | |
| python .github/scripts/detect_yaml_changes.py \ | |
| --source "source-repo/${{ env.SOURCE_YAML_PATH }}" \ | |
| --dest "${{ env.DEST_YAML_PATH }}" \ | |
| --force ${{ github.event.inputs.force_sync || 'false' }} | |
| - name: Check for Changes | |
| id: check | |
| run: | | |
| if [ -f changed_files.txt ] && [ -s changed_files.txt ]; then | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| echo "Changed files:" | |
| cat changed_files.txt | |
| else | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| echo "No changes detected" | |
| fi | |
| - name: Sync YAML Files | |
| if: steps.check.outputs.has_changes == 'true' | |
| id: sync | |
| run: | | |
| python .github/scripts/sync_to_destination.py \ | |
| --source "source-repo/${{ env.SOURCE_YAML_PATH }}" \ | |
| --destination "${{ env.DEST_YAML_PATH }}" \ | |
| --changed-list changed_files.txt | |
| # Convert source paths to destination paths for the action | |
| DEST_FILES="" | |
| while IFS= read -r file; do | |
| BASENAME=$(basename "$file") | |
| DEST_FILES="${DEST_FILES}${{ env.DEST_YAML_PATH }}/${BASENAME}"$'\n' | |
| done < changed_files.txt | |
| echo "synced_files<<EOF" >> $GITHUB_OUTPUT | |
| echo "$DEST_FILES" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: Update API Navigation | |
| if: steps.check.outputs.has_changes == 'true' | |
| uses: DomoApps/documentation-generator-action@main | |
| with: | |
| yaml_input_path: "./${{ env.DEST_YAML_PATH }}" | |
| docs_json_path: "${{ env.DOCS_JSON_PATH }}" | |
| openapi_base_path: "${{ env.OPENAPI_BASE_PATH }}" | |
| process_changed_only: "true" | |
| changed_files: ${{ steps.sync.outputs.synced_files }} | |
| - name: Build PR Body | |
| if: steps.check.outputs.has_changes == 'true' | |
| id: pr-body | |
| run: | | |
| # Build list of changed files for PR body | |
| FILES_LIST="" | |
| if [ -f changed_files.txt ]; then | |
| while IFS= read -r file; do | |
| FILES_LIST="${FILES_LIST}- \`$(basename $file)\`"$'\n' | |
| done < changed_files.txt | |
| fi | |
| # Write PR body to file (safer for multiline content) | |
| cat > pr_body.md << 'PREOF' | |
| ## OpenAPI Sync | |
| This PR syncs updated OpenAPI specifications and navigation from the source repository. | |
| ### Changes | |
| - Synced YAML files from source repo | |
| - Updated docs.json navigation entries | |
| ### Files Updated | |
| PREOF | |
| echo "$FILES_LIST" >> pr_body.md | |
| cat >> pr_body.md << 'PREOF' | |
| --- | |
| *This PR was created automatically by the OpenAPI sync workflow.* | |
| PREOF | |
| - name: Compute branch suffix | |
| if: steps.check.outputs.has_changes == 'true' | |
| id: branch-suffix | |
| run: | | |
| # Hash the sorted changed file names so the same set of changes | |
| # always maps to the same branch, preventing duplicate PRs | |
| HASH=$(sort changed_files.txt | sha256sum | cut -c1-8) | |
| echo "hash=$HASH" >> $GITHUB_OUTPUT | |
| - name: Create Pull Request | |
| if: steps.check.outputs.has_changes == 'true' | |
| uses: peter-evans/create-pull-request@v5 | |
| with: | |
| token: ${{ steps.dest-token.outputs.token }} | |
| commit-message: "docs: Sync OpenAPI specs and update navigation" | |
| title: "docs: Sync OpenAPI specifications" | |
| body-path: pr_body.md | |
| branch: openapi-sync-${{ steps.branch-suffix.outputs.hash }} | |
| delete-branch: true | |
| add-paths: | | |
| ${{ env.DEST_YAML_PATH }} | |
| ${{ env.DOCS_JSON_PATH }} | |
| - name: Summary | |
| if: always() | |
| run: | | |
| echo "## OpenAPI Sync Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ steps.check.outputs.has_changes }}" == "true" ]; then | |
| echo "PR created with the following changes:" >> $GITHUB_STEP_SUMMARY | |
| if [ -f changed_files.txt ]; then | |
| while IFS= read -r file; do | |
| echo "- \`$(basename $file)\`" >> $GITHUB_STEP_SUMMARY | |
| done < changed_files.txt | |
| fi | |
| else | |
| echo "No changes detected - YAML files are up to date" >> $GITHUB_STEP_SUMMARY | |
| fi |