Repository navigation
fix(orca): publish plugins/genie as a tree-only ref instead of a root manifest #2844
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| name: Orca Plugin Ref | ||
|
|
||
| # Republish `plugins/genie` as a standalone git ref that Orca can install. | ||
| # | ||
| # Orca installs a plugin from a git URL + ref (or a local folder) whose ROOT | ||
| # holds `orca-plugin.json`. This repository root can never be that tree: | ||
| # | ||
| # * the loader rejects any tree containing a symlink ("unsafe file path or | ||
| # symlink"), and `docs -> .docs-vendor/genie` is one; | ||
| # * it caps an install at 2000 files / 50 MB, and a dev checkout is ~14k files; | ||
| # * the manifest is nested at `plugins/genie/orca-plugin.json`, invisible to a | ||
| # git source, which only looks at the root. | ||
| # | ||
| # `plugins/genie` on its own is symlink-free, ~132 files / ~1.3 MB, and holds the | ||
| # manifest at its root — so this workflow publishes exactly that subtree: | ||
| # | ||
| # main -> refs/heads/orca-plugin (what orca-marketplace.json points at) | ||
| # dev -> refs/heads/orca-plugin-dev (pre-release channel) | ||
| # | ||
| # SECURITY: `contents: write` is scoped to this one job, which runs no package | ||
| # script, dependency installer, hook, or any executable from the checkout. Every | ||
| # command below is trusted workflow control; the only inputs are a git tree hash | ||
| # derived from the pushed commit and the repository's own ref state. | ||
| # | ||
| # The published ref is TREE-ONLY BY DESIGN: each publish is a fresh parentless | ||
| # root commit carrying just the subtree, force-pushed over the previous one. It | ||
| # has no history, shares no ancestry with main/dev, and must never be merged | ||
| # back. Orca pins the commit it fetched, so a rewritten ref cannot retroactively | ||
| # change an existing install. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, dev] | ||
| paths: | ||
| - 'plugins/genie/**' | ||
| - '.github/workflows/orca-plugin-ref.yml' | ||
| # Manual repair path: republish the current branch tip's subtree. | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| # Serialize per source branch. Never cancel: a cancelled force-push could leave | ||
| # the plugin ref pointing at an older subtree than the branch it mirrors. | ||
| concurrency: | ||
| group: orca-plugin-ref-${{ github.ref }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| publish: | ||
| name: Publish plugins/genie subtree | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| permissions: | ||
| contents: write # force-push the tree-only orca-plugin[-dev] ref | ||
| steps: | ||
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | ||
| with: | ||
| # Only the pushed commit's tree is needed; the publish never walks | ||
| # history. Credentials are bound below with `gh auth setup-git` once | ||
| # the target ref has been resolved. | ||
| fetch-depth: 1 | ||
| persist-credentials: false | ||
|
|
||
| - name: Publish the subtree ref | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| REPO: ${{ github.repository }} | ||
| BRANCH: ${{ github.ref_name }} | ||
| GIT_AUTHOR_NAME: 'github-actions[bot]' | ||
| GIT_AUTHOR_EMAIL: 'github-actions[bot]@users.noreply.github.com' | ||
| GIT_COMMITTER_NAME: 'github-actions[bot]' | ||
| GIT_COMMITTER_EMAIL: 'github-actions[bot]@users.noreply.github.com' | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| case "${BRANCH}" in | ||
| main) TARGET_REF=orca-plugin ;; | ||
| dev) TARGET_REF=orca-plugin-dev ;; | ||
| *) | ||
| echo "::error ::orca-plugin-ref.unexpected-branch ${BRANCH} has no plugin ref mapping" | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| SOURCE_SHA="$(git rev-parse HEAD)" | ||
| SUBTREE="$(git rev-parse "HEAD:plugins/genie")" | ||
| echo "source ${BRANCH}@${SOURCE_SHA} subtree ${SUBTREE} -> refs/heads/${TARGET_REF}" | ||
|
|
||
| # Idempotent: skip when the published ref already carries this exact | ||
| # tree. A missing ref (first publish) is the only tolerated lookup | ||
| # failure — anything else must abort rather than force-push blind. | ||
| PUBLISHED_TREE="" | ||
| REF_STATUS=0 | ||
| REF_SHA="$(gh api "repos/${REPO}/git/ref/heads/${TARGET_REF}" --jq '.object.sha' 2>/dev/null)" || REF_STATUS=$? | ||
| if [ "${REF_STATUS}" -eq 0 ] && [ -n "${REF_SHA}" ]; then | ||
| PUBLISHED_TREE="$(gh api "repos/${REPO}/git/commits/${REF_SHA}" --jq '.tree.sha')" | ||
| else | ||
| echo "refs/heads/${TARGET_REF} not published yet" | ||
| fi | ||
|
|
||
| if [ "${PUBLISHED_TREE}" = "${SUBTREE}" ]; then | ||
| echo "::notice ::orca-plugin-ref.unchanged refs/heads/${TARGET_REF} already carries subtree ${SUBTREE}" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Parentless root commit whose ROOT IS `plugins/genie`. `commit-tree` | ||
| # writes no working tree and copies no history. | ||
| COMMIT="$(git commit-tree "${SUBTREE}" \ | ||
| -m "chore(orca-plugin): plugins/genie subtree of ${BRANCH} ${SOURCE_SHA}")" | ||
|
|
||
| gh auth setup-git | ||
| # Force is structural, not a race override: every publish is a fresh | ||
| # root commit, so the ref can only ever be replaced, never advanced. | ||
| git push --force origin "${COMMIT}:refs/heads/${TARGET_REF}" | ||
|
Comment on lines
+113
to
+116
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a historical successful workflow run is rerun, checkout remains pinned to that run's old push commit, and this unconditional force-push replaces the current Useful? React with 👍 / 👎. |
||
| echo "::notice ::orca-plugin-ref.published refs/heads/${TARGET_REF} = ${COMMIT} (subtree ${SUBTREE})" | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On every normal
devrelease, this workflow publishes the developer-pushed commit, but.github/workflows/version.ymlsubsequently rewrites theplugins/genieversion metadata and pushes a version-only child usinggithub.token; that workflow itself notes thatGITHUB_TOKEN-authored pushes do not trigger workflows. Consequently,orca-plugin-devremains on the pre-bump tree rather than mirroring the resultingdevtip, so pre-release installations receive stale version metadata until an unrelated qualifying push or manual repair occurs. Explicitly dispatch this publisher after the atomic version push or otherwise add a trigger for the version child.Useful? React with 👍 / 👎.