Update Synapse API description and generated artifacts #85
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: Update Synapse API description and generated artifacts | |
| on: | |
| push: | |
| branches: | |
| - synapse/update-synapse-api-workflow-dev # trigger workflow when changes are pushed to this maintenance branch | |
| schedule: | |
| # Run daily at 9 AM UTC (4 AM EST, 1 AM PST) | |
| - cron: '0 9 * * *' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| concurrency: | |
| group: update-synapse-api | |
| cancel-in-progress: false | |
| env: | |
| # NOTE: The following secrets must be defined in the repository or organization settings. | |
| # Some static analyzers may flag them as "Context access might be invalid" even though this | |
| # is valid GitHub Actions syntax. Leave as-is unless the secret names change. | |
| NX_BRANCH: ${{ github.ref_name }} | |
| # Disable Nx Cloud for this workflow to mitigate security risks, since we are automatically | |
| # processing an external API specification. | |
| NX_NO_CLOUD: 'true' | |
| jobs: | |
| extract-devcontainer-image: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| image: ${{ steps.devcontainer.outputs.image }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - id: devcontainer | |
| name: Read .devcontainer/devcontainer.json | |
| run: echo "image=$(jq -r '.image' .devcontainer/devcontainer.json)" >> $GITHUB_OUTPUT | |
| update-synapse-api: | |
| runs-on: ubuntu-latest | |
| needs: extract-devcontainer-image | |
| env: | |
| # By default, Corepack prompts for a confirmation before downloading and enabling | |
| # a package manager. We disable the prompt here to ensure non-interactive execution. | |
| COREPACK_ENABLE_DOWNLOAD_PROMPT: '0' | |
| container: | |
| image: ${{ needs.extract-devcontainer-image.outputs.image }} | |
| # NOTE: The devcontainer image sets its default USER to 'ubuntu'. We override to root here | |
| # (via --user root) so early framework mechanics (actions/checkout writing state files under | |
| # $RUNNER_TEMP, file command APIs, etc.) are guaranteed to have write permission to the mounted | |
| # runner directories without pre-adjusting ownership. After checkout we immediately drop | |
| # privileges for build / generation by chowning only $GITHUB_WORKSPACE and invoking commands | |
| # with 'sudo -u ubuntu'. | |
| # | |
| # Why not stay ubuntu from the start? When the workspace and temp mounts arrive owned by root | |
| # (common when the host bind mounts into the container), starting as ubuntu can cause EACCES | |
| # on state files (e.g. /__w/_temp/_runner_file_commands/save_state_*). Forcing root avoids the | |
| # race/permission edge cases and lets us perform a controlled, minimal privilege drop. | |
| # | |
| # Principles followed: | |
| # * Do NOT chown $RUNNER_TEMP or $RUNNER_TOOL_CACHE (runner-managed, can break file commands) | |
| # * Only chown the repository workspace before running unprivileged steps | |
| # * Use 'sudo -u ubuntu' for generation so artifacts are not root-owned | |
| # * Keep the privileged window as small as possible | |
| options: --user root | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| - name: Adjust ownership & prepare workspace (unprivileged) | |
| run: | | |
| # Change ownership of only the GitHub workspace to ubuntu so dependency installs and | |
| # generated artifacts are written with non-root permissions. We deliberately do NOT | |
| # touch $RUNNER_TEMP or $RUNNER_TOOL_CACHE (runner-managed bind mounts) to avoid EPERM. | |
| chown -R ubuntu:ubuntu "$GITHUB_WORKSPACE" | |
| sudo -u ubuntu bash -lc ' | |
| set -euo pipefail | |
| . ./dev-env.sh | |
| workspace-install | |
| ' | |
| - name: Build API description & regenerate generated projects (unprivileged) | |
| run: | | |
| # Execute build/generation as ubuntu (non-root) to avoid root-owned artifacts. | |
| sudo -u ubuntu bash -lc ' | |
| set -euo pipefail | |
| . ./dev-env.sh | |
| echo "🔄 Building API description (includes downloading latest OpenAPI specification)..." | |
| nx build synapse-api-description | |
| echo "🔄 Regenerating synapse-* generated projects (clients, docs, etc.)..." | |
| nx run-many --target=generate --projects="synapse-*" | |
| ' | |
| - name: Create or update Pull Request | |
| # NOTE: This step still runs as root. We start the container as root for early runner | |
| # internals (checkout, file command state). Only build / generation phases are dropped to | |
| # the unprivileged 'ubuntu' user via 'sudo -u ubuntu'; we do not wrap third‑party actions. | |
| # The workspace files are already owned by ubuntu (we chown'd $GITHUB_WORKSPACE), so the | |
| # only root-originated effects here are git commits / ref updates, which is acceptable. | |
| # To make this unprivileged in future, replace the action with explicit git commands run | |
| # under 'sudo -u ubuntu bash -lc ...', or add a thin wrapper that exports required env vars. | |
| uses: peter-evans/create-pull-request@v7 | |
| with: | |
| branch: synapse/update-synapse-api | |
| delete-branch: true | |
| draft: false | |
| title: 'chore(synapse): update Synapse API description and generated artifacts' | |
| commit-message: 'chore(synapse): update Synapse API description and generated artifacts' | |
| body: | | |
| ## Description | |
| This is an automated update triggered by changes detected in the Synapse OpenAPI specification. | |
| The workflow downloads the latest specification and regenerates dependent generated projects (clients, docs, etc.) to keep them in sync. | |
| ## Review checklist | |
| - [ ] Transition PR from "Ready for Review" -> "Draft" -> "Ready for Review" to trigger CI jobs | |
| - [ ] Verify that the API changes are expected | |
| - [ ] Check that generated artifacts build/compile successfully | |
| - [ ] Run tests to ensure compatibility | |
| - [ ] Review any breaking changes in the API |