Skip to content

Update Synapse API description and generated artifacts #87

Update Synapse API description and generated artifacts

Update Synapse API description and generated artifacts #87

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