sync-documentation #39
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: Sync Documentation Receiver | |
| on: | |
| repository_dispatch: | |
| types: [sync-documentation] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| sync-documentation: | |
| name: Sync Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Validate input | |
| id: validate | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| with: | |
| script: | | |
| const payload = context.payload.client_payload || {}; | |
| const required = ['artifact-id', 'repository', 'run-id']; | |
| const missing = required.filter(field => !payload[field]); | |
| if (missing.length) { | |
| return core.setFailed(`Missing required inputs: ${missing.join(', ')}`); | |
| } | |
| function sanitizeSegment(segment) { | |
| return segment | |
| .replace(/^[.\s]+/, '') | |
| .replace(/[^a-zA-Z0-9._-]/g, '-') | |
| .replace(/-+/g, '-') | |
| .replace(/^-|-$/g, '') | |
| .toLowerCase(); | |
| } | |
| const repoName = payload.repository.split('/')[1] || payload.repository; | |
| const sanitizedRepoName = sanitizeSegment(repoName); | |
| if(!sanitizedRepoName) { | |
| return core.setFailed(`Unable to sanitize repository ${repoName} name for documentation path.`); | |
| } | |
| const docsPath = `application/docs/projects/${sanitizedRepoName}`; | |
| const staticPath = `application/static/${sanitizedRepoName}`; | |
| core.debug(`Sanitized docs path: ${docsPath}`); | |
| core.setOutput('docs-path', docsPath); | |
| core.debug(`Static asset path: ${staticPath}`); | |
| core.setOutput('static-path', staticPath); | |
| core.debug(`Repository: ${payload.repository}`); | |
| core.setOutput('repository', payload.repository); | |
| core.debug(`Run ID: ${payload['run-id']}`); | |
| core.setOutput('run-id', payload['run-id']); | |
| core.debug(`Artifact ID: ${payload['artifact-id']}`); | |
| core.setOutput('artifact-id', payload['artifact-id']); | |
| - name: Download documentation artifact | |
| id: download-artifact | |
| uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| artifact-ids: ${{ steps.validate.outputs['artifact-id'] }} | |
| path: ${{ runner.temp }}/documentation-download-${{ github.run_id }} | |
| repository: ${{ steps.validate.outputs['repository'] }} | |
| run-id: ${{ steps.validate.outputs['run-id'] }} | |
| - name: Prepare documentation content | |
| id: prepare-docs | |
| uses: ./.github/actions/prepare-docs | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| artifact-path: ${{ steps.download-artifact.outputs.download-path }} | |
| source-repository: ${{ steps.validate.outputs['repository'] }} | |
| run-id: ${{ steps.validate.outputs['run-id'] }} | |
| docs-path: ${{ steps.validate.outputs['docs-path'] }} | |
| static-path: ${{ steps.validate.outputs['static-path'] }} | |
| - name: Inject documentation | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| env: | |
| SOURCE_REPOSITORY: ${{ steps.validate.outputs['repository'] }} | |
| DOCS_PATH: ${{ steps.validate.outputs['docs-path'] }} | |
| STATIC_PATH: ${{ steps.validate.outputs['static-path'] }} | |
| PREPARED_DIR: ${{ steps.prepare-docs.outputs.output-path }} | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const sourceRepository = process.env.SOURCE_REPOSITORY; | |
| const docsPath = process.env.DOCS_PATH; | |
| const staticPath = process.env.STATIC_PATH; | |
| const preparedDir = process.env.PREPARED_DIR; | |
| if (!sourceRepository) { | |
| return core.setFailed('Missing source repository from prepare-docs step.'); | |
| } | |
| if (!docsPath) { | |
| return core.setFailed('Missing docs path from prepare-docs step.'); | |
| } | |
| if (!staticPath) { | |
| return core.setFailed('Missing static path from prepare-docs step.'); | |
| } | |
| if (!preparedDir) { | |
| return core.setFailed('Missing prepared directory configuration.'); | |
| } | |
| core.info(`Starting documentation injection from ${sourceRepository}`); | |
| if (!fs.existsSync(preparedDir)) { | |
| return core.setFailed('Prepared documentation directory not found.'); | |
| } | |
| await io.rmRF(docsPath); | |
| await io.mkdirP(path.dirname(docsPath)); | |
| await io.cp(preparedDir, docsPath, { recursive: true }); | |
| // Move static assets if present | |
| const staticAssetsSrc = path.join(docsPath, 'static'); | |
| if (fs.existsSync(staticAssetsSrc)) { | |
| await io.rmRF(staticPath); | |
| await io.mkdirP(path.dirname(staticPath)); | |
| await io.mv(staticAssetsSrc, staticPath); | |
| } | |
| core.info(`Documentation injected into ${docsPath}`); | |
| - name: Generate Documentation | |
| uses: ./.github/actions/generate-docs | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 | |
| id: generate_token | |
| with: | |
| app-id: ${{ vars.CI_BOT_APP_ID }} | |
| private-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }} | |
| - uses: hoverkraft-tech/ci-github-common/actions/create-and-merge-pull-request@5f11437c716059f30c635f90055060e4ef8b31a0 # 0.28.0 | |
| with: | |
| github-token: ${{ steps.generate_token.outputs.token }} | |
| branch: docs/sync-documentation-${{ github.event.client_payload.repository }} | |
| title: "docs(${{ github.event.client_payload.repository }}): update documentation" | |
| body: Update documentation for ${{ github.event.client_payload.repository }} | |
| commit-message: | | |
| docs(${{ github.event.client_payload.repository }}): update documentation | |
| - name: Summary | |
| if: always() | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| env: | |
| STATUS: ${{ job.status }} | |
| SOURCE_REPOSITORY: ${{ steps.validate.outputs['repository'] }} | |
| ARTIFACT_ID: ${{ steps.validate.outputs['artifact-id'] }} | |
| DOCS_PATH: ${{ steps.validate.outputs['docs-path'] }} | |
| STATIC_PATH: ${{ steps.validate.outputs['static-path'] }} | |
| SOURCE_BRANCH: ${{ steps.prepare-docs.outputs.source-branch }} | |
| PROCESSED_FILES: ${{ steps.prepare-docs.outputs.processed-files }} | |
| with: | |
| script: | | |
| const files = process.env.PROCESSED_FILES ? JSON.parse(process.env.PROCESSED_FILES) : []; | |
| const statusText = process.env.STATUS === 'success' | |
| ? 'Documentation committed to public-docs' | |
| : 'Error occurred during documentation sync'; | |
| const filesSummary = files.length | |
| ? `Processed files:\n${files.join('\n')}` | |
| : 'No files were processed.'; | |
| const summaryBuilder = core.summary | |
| .addHeading('Documentation Sync Summary', 2) | |
| .addRaw('\n') | |
| .addList([ | |
| `Source Repository: ${process.env.SOURCE_REPOSITORY}`, | |
| `Source Branch: ${process.env.SOURCE_BRANCH}`, | |
| `Docs Path: ${process.env.DOCS_PATH}`, | |
| `Static Path: ${process.env.STATIC_PATH}`, | |
| `Processed file(s): ${files.length}`, | |
| `Artifact: ${process.env.ARTIFACT_ID}`, | |
| `Status: ${statusText}` | |
| ]) | |
| .addRaw('\n'); | |
| if (files.length > 0) { | |
| summaryBuilder | |
| .addRaw("Processed files:") | |
| .addList(files); | |
| } else { | |
| summaryBuilder.addRaw("Processed files: no files were processed."); | |
| } | |
| summaryBuilder | |
| .addRaw('\n\n') | |
| .addRaw('Build and deployment will be handled by the push to main workflow.'); | |
| await summaryBuilder.write(); |