Docs navigation
CI Integration
GenX API stays CLI-first as a product, but GitHub workflows should usually start with the official genxapi-action wrapper:
genxapi-actionis the recommended GitHub workflow entrypoint- the
generatecommand can run headless dry-run planning with a JSON plan file - the
diffcommand can produce contract comparison output for humans or automation - direct CLI execution still works in GitHub Actions and other CI systems
- dry runs resolve contracts, template choice, output paths, planned lifecycle actions, and next-step reporting before any files are written
This keeps the boundaries narrow:
- backend boundary: your OpenAPI or Swagger contract
- consumer boundary: the generated package interface
- template boundary: Orval or Kubb still own generator-specific capability behavior
- core boundary: GenX API owns orchestration, metadata, lifecycle, and workflow reporting
Choose your automation path
- Use the official GitHub Action when your automation already lives in GitHub Actions and you want the canonical workflow wrapper around GenX API.
- Use the CLI directly when you want the most flexible path, need the same automation pattern across GitHub Actions, GitLab CI, CircleCI, and local runners, or want full control over installation and invocation.
See Official GitHub Action for the wrapper repository and migration note.
Recommended for GitHub Actions
Use the official action as the default GitHub workflow surface:
name: Backend Package Generation
on:
pull_request:
paths:
- openapi/**/*
- genxapi.config.json
push:
branches:
- main
paths:
- openapi/**/*
- genxapi.config.json
jobs:
generate-sdk:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4
- id: genx
uses: genxapi/genxapi-action@main
with:
config: ./genxapi.config.json
contract: ./openapi/petstore.yaml
output-path: ./sdk/petstore-sdk
contract-version: ${{ github.sha }}
dry-run: ${{ github.event_name == 'pull_request' }}
plan-output: ./artifacts/genxapi-plan.json
release-manifest-output: ./artifacts/genxapi-release.json
publish-mode: ${{ github.ref == 'refs/heads/main' && 'config' || 'off' }}
Use a pinned release tag from genxapi-action once you standardise the version you want in production.
Backend-Initiated Example
Reference workflow: docs/backend-package-generation.workflow.yml
name: Backend Package Generation
on:
pull_request:
paths:
- openapi/**/*
- genxapi.config.json
push:
branches:
- main
paths:
- openapi/**/*
- genxapi.config.json
jobs:
generate-sdk:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4
- id: genx
uses: genxapi/genxapi-action@main
with:
config: ./genxapi.config.json
contract: ./openapi/petstore.yaml
output-path: ./sdk/petstore-sdk
contract-version: ${{ github.sha }}
dry-run: ${{ github.event_name == 'pull_request' }}
plan-output: ./artifacts/genxapi-plan.json
release-manifest-output: ./artifacts/genxapi-release.json
publish-mode: ${{ github.ref == 'refs/heads/main' && 'config' || 'off' }}
- name: Show resolved plan
run: |
cat "${{ steps.genx.outputs.plan-path }}"
if [ -n "${{ steps.genx.outputs.release-manifest-path }}" ]; then
cat "${{ steps.genx.outputs.release-manifest-path }}"
fi
Why this is the intended backend flow:
- the workflow starts from the backend-owned contract file
- the only GenX API inputs are the config file plus optional automation overrides
- the generated package boundary remains the package directory, not internal generator output paths
- publish behavior stays opt-in and config-driven unless CI explicitly overrides it
Alternative: direct CLI wiring
If you want to wire the CLI yourself inside GitHub Actions or reuse the same pattern in another CI system, prefer the human-facing command:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Run GenX API directly
shell: bash
run: |
args=(
--config ./genxapi.config.json
--contract ./openapi/petstore.yaml
--output-path ./sdk/petstore-sdk
--contract-version "${GITHUB_SHA}"
--plan-output ./artifacts/genxapi-plan.json
--release-manifest-output ./artifacts/genxapi-release.json
--publish-mode "${{ github.ref == 'refs/heads/main' && 'config' || 'off' }}"
)
if [ "${{ github.event_name }}" = "pull_request" ]; then
npx genxapi -- generate "${args[@]}" --dry-run
else
npx genxapi -- generate "${args[@]}"
fi
This keeps the command surface product-aligned while avoiding a GitHub-specific wrapper.
Headless Dry Run and Plan Output
generate --dry-run now resolves enough of the run to be trustworthy in CI:
- template kind and template package
- contract source and generator input
- output workspace, target, and schema paths
- planned GenX API actions such as manifest writing, repository sync, and publish steps
- selected template capabilities and dependency plan
Example:
npx genxapi diff \
--base ./openapi/petstore-before.yaml \
--head ./openapi/petstore-after.yaml \
--format json \
--output ./artifacts/genxapi-diff.json \
--release-manifest-output ./artifacts/genxapi-release.json
npx genxapi generate \
--config ./genxapi.config.json \
--dry-run \
--plan-output ./artifacts/genxapi-plan.json \
--release-manifest-output ./artifacts/genxapi-release.json \
--contract ./openapi/petstore.yaml \
--output-path ./sdk/petstore-sdk
The JSON plan file is the recommended CI hand-off artifact before you allow generation or publishing. The release manifest is the recommended place to join contract diff output and generation metadata into one CI artifact.
CLI Automation Overrides
The supported CI-facing generate overrides are intentionally small:
--contractoverrides the contract source for a single-client config--output-pathoverrides the generated package directory--publish-modeflips publish automation betweenconfig,off,npm,github, andboth--contract-versionrecords external contract version metadata in the plan and manifest--plan-outputwrites a JSON plan file for CI parsing--release-manifest-outputwrites release lifecycle metadata that can be shared withgenxapi diff
These flags do not collapse template behavior into the shared automation surface. They only control orchestration inputs that belong in GenX API core.
Logging and Failure Behavior
Headless runs are now clearer by default:
- dry runs print a real generation plan instead of exiting after config validation
- CI mode avoids spinner-only progress reporting
- contract URLs are sanitised before they are echoed in plan and manifest metadata
- top-level CLI failures pass through secret redaction before they hit stderr
Operational guidance:
- keep tokens in environment variables referenced by config, never inline in URLs
- use
publish-mode: offon pull requests so validation stays side-effect free - promote to
publish-mode: configor a narrower explicit mode only on protected branches
Direct CLI Usage
If you do not want to use GitHub Actions, the same surface is available directly:
npx genxapi generate \
--config ./genxapi.config.json \
--contract ./openapi/petstore.yaml \
--output-path ./sdk/petstore-sdk \
--publish-mode off \
--dry-run \
--plan-output ./artifacts/genxapi-plan.json \
--release-manifest-output ./artifacts/genxapi-release.json
This is the supported path for other CI providers as well.
Migration note
Earlier versions of this documentation referenced a repository-root GitHub Action in genxapi. That wrapper now lives in genxapi-action.
Keep using the same GenX API config, CLI flags, manifests, and diff flow. Only the GitHub Actions wrapper source moves to the dedicated action repository.
What Is Still Not Shipped
This phase still does not add:
- breaking vs non-breaking structural diffing
- automatic SemVer decisions or release-note generation
- template flattening between Orval and Kubb
- consumer-repo coupling or dist-path based automation
Those stay in later phases.
Next Steps
- Read Generation Manifest for the metadata produced after a real run.
- Read Versioning and releases for the current publish and release surface.
- Read Release lifecycle for the current diff-to-generation handoff.
- Read Official GitHub Action when you want the dedicated GitHub wrapper repository.
Next: Templates →