chore(cla): call the shared CLA reusable instead of a self-hosted job (ENG-2017) - #222
Merged
Merged
Conversation
… (ENG-2017) The CLA check ran on mdb-dev, a pod inside the newdev cluster. Its triggers, pull_request_target and issue_comment, both run in base-repo context, so GitHub's fork-approval gate never applied and any account could start that pod by opening a pull request or leaving a comment. Replace the hand-rolled job with the reusable anton, cowork and cowork-server already call. It runs on ubuntu-latest, pins the third-party action to a commit, grants actions read rather than write, and skips the job outright for a comment that is not a CLA comment. Refs: ENG-2017
7 tasks
…017) Both URLs the org uses for this document are rename redirects that resolve to the same repository and serve byte-identical content. A redirect is fine until somebody creates a repository at the old name, and this is the page a contributor reads before agreeing to it. Name the repository that actually holds the file. Refs: ENG-2017
…2017)
The allowlist moved into mindsdb/github-actions and is bots only. This repo
carried one of six hand-maintained copies naming people, and 11 of the 25 names
across those copies had already left the org while still being exempt from
signing. Staff sign like everybody else now. A bot cannot sign, so the two that
actually open pull requests in this org stay exempt in the reusable.
Dropping the line also drops two defects that rode inside it. `bot*` compiled to
an unanchored `new RegExp("bot.*").test(login)`, so it exempted any login
containing "bot", `robotnik` and `sabotage` included. And `Stpmax` never matched
the real login `StpMax`, because non-wildcard entries are compared with a
case-sensitive `===`.
Needs mindsdb/github-actions#56 first, which gives the input a default.
This repo accepts pull requests from outside contributors and had no CODEOWNERS at all, so a workflow change here needed no particular reviewer. Everything under .github/ decides what runs in CI, on which runner, and with which secrets in scope, which is a trust boundary rather than product code. Auto-request only for now. Making it a hard gate needs require_code_owner_reviews in branch protection, which this repo does not have; that rides ENG-2013's org ruleset.
mindsdb-devops
approved these changes
Aug 28, 2026
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
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User story
As a maintainer of this repository
I want the CLA check to run on a disposable GitHub-hosted runner
So that a stranger opening a pull request cannot start a pod inside our clusters
Why this matters
cla.ymlran onmdb-dev, which is not a GitHub VM. It is a pod inside our newdevEKS cluster, holding a Kubernetes identity, an AWS role and a filesystem other
repositories' credentialed jobs write into.
This workflow triggers on
pull_request_targetandissue_comment. Both run inbase-repo context, so GitHub's fork-approval gate never applies: the run starts
when a pull request opens or a comment is posted, from any account, with nobody
clicking anything. Outside accounts have already done it here.
The job also ran
contributor-assistant/github-action@v2.6.1, a mutable tag, sowhoever controls that tag upstream chose what ran on the pod.
What happens today
flowchart TD S["Any GitHub account"] --> E["Opens a PR, or comments on any issue"] E --> N["Base-repo trigger, so no approval gate applies"] N --> J["Job claims a pod on mdb-dev"] J --> P["Four write scopes on GITHUB_TOKEN"] J --> A["Third-party action on a mutable tag"]What should happen
flowchart TD S["Any GitHub account"] --> E["Opens a PR, or comments on any issue"] E --> G{"Job condition: a PR event, or a CLA comment?"} G -->|"no, an unrelated comment"| SKIP["Job skipped, no runner claimed"] G -->|"yes"| J["Job runs on ubuntu-latest"] J --> A["Action pinned to a commit SHA"]Acceptance criteria
mdb-dev.issue_commentthat is not a CLA comment leaves the job skipped, with no runner claimed.How to test
clabranch.Notes for the reviewer
The allowlist is gone from this file, and staff now sign like everybody else. Fifteen repositories carried six different hand-maintained copies naming 25 people between them, and 11 of those 25 had already left the org while still being exempt from signing. It now defaults in the reusable and is bots only:
dependabot[bot]andmindsdb-release-train[bot], the two that actually open pull requests in this org. A bot cannot post the agreement sentence, so without an exemption its pull request is red forever.Dropping the line also drops two live defects that rode inside it.
bot*compiled to an unanchorednew RegExp("bot.*").test(login), so it exempted any login containing "bot", includingrobotnikandsabotage; anyone could opt out of the CLA by choosing a username. AndStpmaxnever matched the real loginStpMax, because non-wildcard entries use a case-sensitive===. Needs mindsdb/github-actions#56, which gives the input its default..github/gets a code owner. This repo had no CODEOWNERS, so a change to what runs in CI, on which runner, and with which secrets in scope needed no particular reviewer, on a repo that accepts outside pull requests. Auto-request only for now: a hard gate needsrequire_code_owner_reviewsin branch protection, which this repo does not set and which rides ENG-2013's org ruleset. Faking it here would be a file that looks like a control and is not one.The green
CLAssistantrow on this pull request does not exercise this change.pull_request_targetloads the workflow from the base branch, so the check that passed here is the copy this PR replaces, running onmdb-dev. The new job cannot test itself on its own pull request; it is exercised on the first pull request opened after this merges.The
on:andpermissions:blocks swap places, which is why the diff looks bigger than it is. Every converted wrapper now reads name, permissions, triggers, job, in that order. No trigger and no scope changes as a result of the move itself.This replaces a hand-rolled job with the reusable
anton,coworkandcowork-serveralready call. Nothing new was invented. The reusable is hardened in the same change set at mindsdb/github-actions, which pins the action to a commit, moves the event filter from the step to the job, drops itsruns-oninput entirely, and reducesactions: writetoactions: read.The
actionsscope is read, not write, and that is deliberate. The upstream README asks for write. The only write it buys ispullRerunRunner.tsre-running a previously failed CLA run, and that API refuses aGITHUB_TOKEN, so the call already failed and was swallowed. Dropping the scope altogether does break the job, because the same file lists the repository's workflows first andmain.tsturns any throw into a failure.The signature ledger is untouched.
path-to-signaturesandbranchstill resolve to the same file on the same branch, so every existing signature stays where it is.The agreement link names the canonical repository rather than a redirect. Every URL the org used for this document was a rename redirect. They all resolve to the same file and serve byte-identical content, so nothing changes for a reader today. A redirect stops being harmless the moment somebody creates a repository at the old name, and this is the page a contributor reads before agreeing to it.
Verified locally
actionlinton the changed filemindsdb/github-actions@main:runs-on: ubuntu-latest, and after this change set the input does not exist at all.gh search codeover the org:anton,coworkandcowork-servercall the reusable and none of them passesruns-on.clabranch, 2 signers, unchanged by this PR.Ships with
One behaviour across eleven repositories, one pull request each. The anchor is
mindsdb/github-actions, which hardens the shared reusable this file now calls.There is no
Deploys:line and no pull request environment: these are libraryrepositories with no deploy pipeline, so nothing here brings up an environment.
Merge order: the anchor first, and that is a requirement rather than a
preference. This wrapper grants
actions: read, and untilmindsdb/github-actions#55 merges the reusable still declares
actions: write.A called workflow's permissions are enforced when its file is loaded, so a
callee naming a scope its caller has not granted rejects the whole run as a
startup_failurewith zero jobs, and there is no job left to report it. Therun is red, the CLA gate is down, and nothing announces either.
Refs: ENG-2017