{"id":49441301,"url":"https://github.com/orkspace/orkestra-action","last_synced_at":"2026-06-17T01:01:55.925Z","repository":{"id":354717642,"uuid":"1219071806","full_name":"orkspace/orkestra-action","owner":"orkspace","description":"The official GitHub Action for Orkestra — runs the full ork CLI surface from any workflow","archived":false,"fork":false,"pushed_at":"2026-06-05T22:53:30.000Z","size":127,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T23:10:44.037Z","etag":null,"topics":["automation","ci","cicd","github-action","gitops","kubernetes","operators","ork","orkestra","rbac"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/orkspace.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-23T13:54:12.000Z","updated_at":"2026-06-05T22:52:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/orkspace/orkestra-action","commit_stats":null,"previous_names":["orkspace/orkestra-action"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/orkspace/orkestra-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orkspace%2Forkestra-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orkspace%2Forkestra-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orkspace%2Forkestra-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orkspace%2Forkestra-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orkspace","download_url":"https://codeload.github.com/orkspace/orkestra-action/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orkspace%2Forkestra-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33964367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","ci","cicd","github-action","gitops","kubernetes","operators","ork","orkestra","rbac"],"created_at":"2026-04-29T20:01:17.457Z","updated_at":"2026-06-17T01:01:55.911Z","avatar_url":"https://github.com/orkspace.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Orkestra GitHub Action\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"logo.svg\" width=\"140\" alt=\"Orkestra Logo\"\u003e\n\u003c/div\u003e\n\nThe official GitHub Action for Orkestra — runs the full `ork` CLI surface from any workflow.\n\n---\n\n## How it works\n\n1. Installs the `ork` CLI (pinned or latest)\n2. Runs only the commands you enable — everything else is skipped\n3. Exposes file paths as outputs for steps that produce artifacts\n\nSteps run in this order: **validate → simulate → plan → template → generate → e2e → registry**\n\n---\n\n## Quick start\n\n```yaml\n- uses: orkspace/orkestra-action@v1\n  with:\n    validate: \"true\"\n    simulate: \"true\"\n    e2e: \"true\"\n```\n\nAll three commands auto-detect their files (`katalog.yaml`, `simulate.yaml`, `e2e.yaml`) from `working-directory`.\n\n---\n\n## Inputs\n\n### Common\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `ork-version` | `latest` | Version of the `ork` CLI to install |\n| `working-directory` | `.` | Directory to run all commands in |\n\n### `validate`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `validate` | `\"\"` | `'true'` = auto-detect. Path = validate that file. Empty = skip. |\n| `validate-depth` | `single` | `full` → `ork validate --full` (RBAC, dependency graph, per-CRD permissions) |\n\n### `simulate`\n\nRuns `ork simulate` — no cluster required. Reads `simulate.yaml` (assert mode) or `e2e.yaml`/`katalog.yaml` (op-print mode).\n\n\u003e `simulate` in CI fails on cycle errors and on `expect:` assertion failures. For full value, commit a `simulate.yaml` with assertions alongside your katalog. Generate one with `ork simulate init`.\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `simulate` | `\"\"` | `'true'` = auto-detect. Path = use that file. Empty = skip. |\n| `simulate-depth` | `single` | `full` → `ork simulate ./...` (discovers all simulate.yaml + e2e.yaml recursively) |\n| `simulate-katalog` | `\"\"` | Explicit `katalog.yaml` path. Always wins over `simulate` and `simulate-depth`. |\n| `simulate-cr` | `\"\"` | Explicit `cr.yaml` path. Paired with `simulate-katalog`. Falls back to `cr.yaml` in cwd if omitted. |\n| `simulate-crd` | `\"\"` | CRD name to target when the katalog defines multiple. All CRDs if omitted. |\n| `simulate-cycles` | `\"\"` | Maximum reconcile cycles (`ork simulate --cycles`). |\n| `simulate-skip-external` | `true` | Stub `external:` HTTP calls — no real network. Default `true` since CI has no dev server. |\n| `simulate-skip` | `\"\"` | Comma-separated path patterns to skip in `./...` discovery. |\n| `simulate-debug` | `false` | Save per-cycle op trace to `simulate-debug-output` (`ork simulate --debug-ops`). |\n| `simulate-debug-output` | `simulate-debug.txt` | File to write the `--debug-ops` trace to. |\n\n### `plan`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `plan` | `\"\"` | Path to `katalog.yaml` to diff against the deployed Katalog. Empty = skip. |\n| `plan-bundle` | `\"\"` | Path to a `bundle.yaml` — reads the deployed Katalog from it. No cluster access needed. |\n| `plan-cm` | `\"\"` | Path to a `configmap.yaml` — reads the deployed Katalog from it. No cluster access needed. |\n| `plan-namespace` | `orkestra-system` | Namespace — only used when neither `plan-bundle` nor `plan-cm` is set. |\n| `plan-output` | `plan.txt` | File to write the plan diff output to. |\n| `comment-on-pr` | `\"\"` | Set to `\"true\"` to post the plan diff as a PR comment. Requires `pull-requests: write` on the job. |\n| `github-token` | `${{ github.token }}` | Token used to post the PR comment. Only used when `comment-on-pr` is set. |\n\nOne of `plan-bundle` or `plan-cm` is required when `plan` is set.\n\n### `template`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `template` | `\"\"` | Path to `katalog.yaml` to render the fully-expanded runtime Katalog. Empty = skip. |\n| `template-yaml-output` | `template.yaml` | Output file for the YAML render (`ork template --yaml`). |\n| `template-json-output` | `template.json` | Output file for the JSON render (`ork template --json`). |\n\n### `generate bundle`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `generate-bundle` | `\"\"` | Path to `katalog.yaml`. Empty = skip. |\n| `generate-bundle-output` | `bundle.yaml` | Output file path |\n| `generate-bundle-namespace` | `orkestra-system` | Kubernetes namespace |\n\n### `generate configmap`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `generate-configmap` | `\"\"` | Path to `katalog.yaml` or `komposer.yaml`. Empty = skip. |\n| `generate-configmap-output` | `configmap.yaml` | Output file path |\n| `generate-configmap-namespace` | `orkestra-system` | Kubernetes namespace |\n\n### `generate rbac`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `generate-rbac` | `\"\"` | Path to `katalog.yaml`. Empty = skip. |\n| `generate-rbac-output` | `rbac.yaml` | Output file path |\n| `generate-rbac-namespace` | `orkestra-system` | Namespace for the ServiceAccount |\n\n### `generate registry` (typed operators)\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `generate-registry` | `\"\"` | Comma-separated project directories. Writes `zz_generated_runtime_registry.go` in each. Empty = skip. |\n\n### `e2e`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `e2e` | `\"\"` | `'true'` = auto-detect `e2e.yaml`. Path = use that file. Empty = skip. |\n| `e2e-depth` | `single` | `full` → `ork e2e ./...` (discovers all e2e.yaml files recursively) |\n| `e2e-keep-cluster` | `false` | Keep the kind cluster after the test (useful for debugging) |\n| `e2e-cluster` | `\"\"` | Use an existing kubectl context instead of creating a cluster |\n| `e2e-wait` | `3s` | Wait between tests in `./...` discovery mode. Lets clusters fully tear down. |\n| `e2e-skip` | `\"\"` | Comma-separated path patterns to skip in `./...` discovery. |\n\n### `registry push`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `registry-push` | `\"\"` | `\"name:version /path/to/dir\"` or `\"/path/to/dir\"`. Empty = skip. |\n| `registry-push-force` | `false` | Push even if e2e fails or metadata version differs |\n| `registry-push-no-e2e` | `false` | Skip the e2e gate (even if `e2e.yaml` is present) |\n| `registry-url` | `\"\"` | OCI registry URL. Also read from `ORK_REGISTRY` env var. |\n| `registry-username` | `\"\"` | Registry username |\n| `registry-password` | `\"\"` | Registry password or token |\n\n### `registry pull`\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `registry-pull` | `\"\"` | `\"name:version\"`. Empty = skip. |\n| `registry-pull-out` | `\"\"` | Directory to extract the pulled pattern into |\n\n---\n\n## Outputs\n\n| Output | Description |\n|--------|-------------|\n| `plan-file` | Path to the plan diff output file (default `plan.txt`) |\n| `plan-no-changes` | `\"true\"` if `ork plan` detected no changes — the deployed config is already up to date |\n| `template-yaml-file` | Path to the YAML-rendered runtime Katalog |\n| `template-json-file` | Path to the JSON-rendered runtime Katalog |\n| `bundle-file` | Path to the generated `bundle.yaml` |\n| `configmap-file` | Path to the generated `configmap.yaml` |\n| `rbac-file` | Path to the generated `rbac.yaml` |\n| `registry-file` | Path to the generated `zz_generated_runtime_registry.go` |\n| `simulate-debug-file` | Path to the `--debug-ops` trace file (set when `simulate-debug: true`) |\n| `pattern-path` | Local path where the pulled pattern was extracted |\n\n---\n\n## Examples\n\n### Standard CI — validate, simulate, e2e\n\nThe CI pyramid: each layer is cheaper than the next. Simulate catches logic errors without a cluster.\n\n```yaml\n- uses: orkspace/orkestra-action@v1\n  with:\n    validate: \"true\"\n    simulate: \"true\"    # reads simulate.yaml → fails on assertion errors\n    e2e: \"true\"         # reads e2e.yaml → full cluster test\n```\n\n### Simulate with explicit katalog and CR\n\nUse when you want to run simulate directly against a katalog without a `simulate.yaml` file.\n\n```yaml\n- uses: orkspace/orkestra-action@v1\n  with:\n    simulate-katalog: ./katalog.yaml\n    simulate-cr: ./cr.yaml\n    simulate-cycles: \"5\"\n```\n\n### Discovery mode — simulate and e2e across all examples\n\n```yaml\n- uses: orkspace/orkestra-action@v1\n  with:\n    simulate-depth: full\n    simulate-skip: \"vendor,testdata\"\n    e2e-depth: full\n    e2e-skip: \"vendor,testdata\"\n    e2e-wait: \"5s\"\n```\n\n### Matrix across multiple operators\n\n```yaml\nstrategy:\n  matrix:\n    example:\n      - examples/beginner/01-hello-website\n      - examples/beginner/02-with-service\n      - examples/advanced/09-hooks\n\nsteps:\n  - uses: actions/checkout@v4\n  - uses: orkspace/orkestra-action@v1\n    with:\n      working-directory: ${{ matrix.example }}\n      validate: \"true\"\n      simulate: \"true\"\n      e2e: \"true\"\n```\n\n### Generate and upload a deployment bundle\n\n```yaml\n- name: Generate bundle\n  uses: orkspace/orkestra-action@v1\n  id: bundle\n  with:\n    generate-bundle: ./katalog.yaml\n\n- name: Upload\n  uses: actions/upload-artifact@v4\n  with:\n    name: bundle\n    path: ${{ steps.bundle.outputs.bundle-file }}\n```\n\n### Typed operator — generate registry, build image, deploy, then e2e\n\n```yaml\n- uses: orkspace/orkestra-action@v1\n  with:\n    validate: \"true\"\n    simulate: \"true\"\n    generate-registry: \".\"\n\n- run: CGO_ENABLED=0 go build -tags runtime -o ./bin/operator ./cmd/operator\n\n- uses: docker/build-push-action@v5\n  with:\n    context: .\n    push: true\n    tags: ghcr.io/myorg/my-operator:${{ github.sha }}\n\n- run: |\n    helm upgrade --install orkestra orkestra/orkestra \\\n      --set runtime.image.repository=ghcr.io/myorg/my-operator \\\n      --set runtime.image.tag=${{ github.sha }} \\\n      --namespace orkestra-system --create-namespace --wait\n\n- uses: orkspace/orkestra-action@v1\n  with:\n    e2e: \"true\"\n    e2e-cluster: kind-ork-e2e\n```\n\nSee [`examples/typed-operator.yml`](examples/typed-operator.yml) for the full workflow.\n\n### Plan diff commented on PR\n\nAdd `comment-on-pr: \"true\"` to post the plan diff as a PR comment. The job needs `pull-requests: write`.\n\n```yaml\njobs:\n  plan:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: write\n    steps:\n      - uses: actions/checkout@v4\n      - uses: orkspace/orkestra-action@v0.1.0\n        with:\n          plan: katalog.yaml\n          plan-bundle: bundle.yaml\n          comment-on-pr: \"true\"\n```\n\nThe comment shows the full `ork plan` diff. If there are no changes, it posts a clean \"no changes\" message instead. Output is truncated at 60,000 characters to stay within GitHub's comment limit.\n\n**Cross-job pattern** — when you need the plan job to have minimal permissions and the comment job to have `pull-requests: write` separately:\n\n```yaml\njobs:\n  plan:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n    outputs:\n      plan-no-changes: ${{ steps.ork.outputs.plan-no-changes }}\n    steps:\n      - uses: actions/checkout@v4\n      - name: Run ork plan\n        id: ork\n        uses: orkspace/orkestra-action@v0.1.0\n        with:\n          plan: katalog.yaml\n          plan-bundle: bundle.yaml\n      - uses: actions/upload-artifact@v4\n        if: steps.ork.outputs.plan-no-changes != 'true'\n        with:\n          name: ork-plan-${{ github.run_id }}\n          path: ${{ steps.ork.outputs.plan-file }}\n          retention-days: 3\n\n  comment:\n    needs: plan\n    runs-on: ubuntu-latest\n    permissions:\n      pull-requests: write\n    steps:\n      - uses: orkspace/orkestra-action/comment-plan-on-pr@v0.1.0\n        with:\n          plan-artifact: ork-plan-${{ github.run_id }}\n          no-changes: ${{ needs.plan.outputs.plan-no-changes }}\n          plan-status: ${{ needs.plan.result }}\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n```\n\nSee [`examples/plan-pr.yml`](examples/plan-pr.yml) for both patterns side by side.\n\n### Publish a pattern on tag push\n\n```yaml\n- uses: orkspace/orkestra-action@v1\n  with:\n    validate: \"true\"\n    simulate: \"true\"\n    registry-push: \"my-operator:${{ github.ref_name }} .\"\n    registry-url: \"ghcr.io/${{ github.repository_owner }}/patterns\"\n    registry-username: ${{ github.actor }}\n    registry-password: ${{ secrets.GITHUB_TOKEN }}\n```\n\n---\n\n## License\n\n[Apache 2.0](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forkspace%2Forkestra-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forkspace%2Forkestra-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forkspace%2Forkestra-action/lists"}