Skip to content

feat(cla): gate web/ PRs on a signed Contributor License Agreement#1387

Merged
rumblefrog merged 1 commit into
mainfrom
feat/web-panel-cla
May 14, 2026
Merged

feat(cla): gate web/ PRs on a signed Contributor License Agreement#1387
rumblefrog merged 1 commit into
mainfrom
feat/web-panel-cla

Conversation

@rumblefrog
Copy link
Copy Markdown
Member

Summary

Set up dual-licensing infrastructure for the web panel so the maintainer
can keep offering it under CC BY-SA (community / hobby use) while also
offering a separate commercial license (production / hosting providers)
without having to track down every contributor for every future
relicensing decision.

The CLA is the standard mechanism for this — same legal shape GitLab,
Discourse, and Plex use. Contributors keep copyright in their work
(§2); the maintainer gets a perpetual, irrevocable, worldwide,
royalty-free, sublicensable licence with the explicit right to
relicense under any terms, including proprietary or commercial
(§3(b)).

Scope

  • web/** only. Plugin contributions under game/addons/sourcemod/**
    stay pure GPLv3 — strong copyleft already blocks quiet relicensing,
    so layering a CLA on top would only add friction without unlocking
    anything.
  • Allowlisted from the gate: the maintainer (rumblefrog) plus
    all GitHub App bots (*[bot], which covers Dependabot today and any
    future GitHub App).
  • Mixed PRs (web/ + plugins) fire the gate via the web/ half; one
    signature unblocks both.

What's in this PR

  • CLA.md (new) — 10-section agreement, ~1 page. The load-bearing
    clauses are §3 (licence grant with sublicense + relicense rights),
    §4 (Apache-2.0-shape patent grant with the standard litigation
    termination), §8 (scope-limited to web/**).
  • .github/workflows/cla.yml (new) — uses
    contributor-assistant/github-action@v2.6.1.
    Triggers on pull_request_target with paths: ['web/**', 'CLA.md', '.github/workflows/cla.yml']
    plus issue_comment for the sign flow. Job-level if: filter so
    unrelated comments don't burn action minutes. Signatures land on an
    auto-created orphan branch cla-signatures under
    signatures/cla.json.
  • CONTRIBUTING.md (new) — pointers to AGENTS.md / ARCHITECTURE.md
    plus the rationale and how-to-sign for contributors. Also fixes the
    long-dangling reference from .github/PULL_REQUEST_TEMPLATE.md
    line 29 (which already mentioned "the CONTRIBUTING document"
    even though it didn't exist).
  • README.md — Contributing section links the new CONTRIBUTING.md
    and notes the CLA. Also bundles in-progress edits from before
    this work (Sponsors section + License commercial-license callout)
    since they document the model the CLA actually enables — splitting
    them would create dangling references from the new CONTRIBUTING.md.
  • .github/PULL_REQUEST_TEMPLATE.md — CONTRIBUTING checkbox now
    links to the new file; bottom-of-template note about the CLA bot's
    sign flow. No new checkbox (bot enforces via status check, a
    self-checked box would be redundant + falsifiable).
  • AGENTS.md — three additions: new row in "Keep the docs in sync"
    table, new row in "Where to find what" table, and a new Conventions
    subsection "Contributor License Agreement gate (web/**)" with the
    load-bearing rule that the sign phrase is byte-identical in three
    places (CLA.md §10 / workflow if: / custom-pr-sign-comment).

What happens on merge

  1. First PR after merge that touches web/** from a non-allowlisted
    contributor:
    • The action creates the cla-signatures orphan branch with an
      empty signatures/cla.json.
    • Posts a comment with one-line sign instructions.
    • Sets a license/cla status check (red until signed).
  2. Contributor comments the exact sign phrase; bot records signature
    and flips status check to green within seconds.
  3. Future PRs from the same contributor pass the gate automatically.

Known follow-ups (deliberately out of scope)

  • Historical contributors haven't signed. Their pre-CLA web-panel
    contributions aren't covered by the new grant, so strictly speaking
    the relicense applies "from this point forward". GitLab / Discourse
    / Plex either (a) get retroactive sign-off from material historical
    contributors, or (b) note the relicense applies from version X.Y
    onward. Separate piece of work, not blocked by this PR.
  • No corporate (CCLA) variant yet — defer until a company actually
    contributes. Adding a second document is easy then.

Test plan

  • CI passes on this PR (the new CLA workflow won't fire on this
    branch since I'm in the allowlist; other gates should be
    unaffected — the workflow is path-filtered to web/** and this
    PR touches it via paired docs only).
  • After merge: open a draft test PR from a second account touching
    web/**, verify the bot comments with sign instructions, sign,
    verify status check flips green. Close the draft PR.
  • Verify cla-signatures orphan branch was auto-created with the
    test signature.
  • Check that a plugin-only PR (game/addons/sourcemod/** change)
    does not trigger the CLA workflow.

Set up the dual-licensing infrastructure for the web panel so the
maintainer can offer it under both CC BY-SA (community / hobby use)
and a separate commercial license (production / hosting providers)
without having to contact every contributor individually for every
future relicensing decision.

New files:

- CLA.md — 10-section agreement, web/-scoped, contributor keeps
  copyright (§2), maintainer gets a perpetual, irrevocable,
  worldwide, royalty-free, sublicensable licence with the explicit
  right to relicense under any terms including proprietary /
  commercial (§3(b)). Same legal shape as GitLab / Discourse / Plex.
- .github/workflows/cla.yml — contributor-assistant/github-action
  @v2.6.1 gated on pull_request_target paths web/** + issue_comment
  (for the sign flow). Allowlist: rumblefrog + *[bot]. Signatures
  land on an orphan branch cla-signatures created on first run.
- CONTRIBUTING.md — pointers to AGENTS.md / ARCHITECTURE.md plus
  the rationale and how-to-sign for the CLA. Also fixes the
  dangling reference from .github/PULL_REQUEST_TEMPLATE.md.

Updates:

- README.md — Contributing section links CONTRIBUTING.md + mentions
  the CLA. The new Sponsors block and the License section's
  commercial-license callout (in-progress copy from before the CLA
  work) ship in the same commit since they document the model the
  CLA enables.
- .github/PULL_REQUEST_TEMPLATE.md — CONTRIBUTING checkbox links to
  the new file; bottom-of-template note about the CLA bot's sign
  flow.
- AGENTS.md — row in "Keep the docs in sync", row in "Where to find
  what", and a new "Contributor License Agreement gate (web/**)"
  subsection in Conventions documenting the paths-filter scope,
  allowlist source-of-truth, signatures branch, and the load-bearing
  rule that the sign phrase stays byte-identical across CLA.md §10,
  the workflow's job-level if:, and custom-pr-sign-comment.

Scope is web/** only — plugins under game/addons/sourcemod/** stay
GPLv3 (strong copyleft already blocks quiet relicensing). Mixed PRs
trigger the gate via the web/** half; one signature unblocks both.

Known follow-up: historical contributors haven't signed. Their
pre-CLA web-panel contributions aren't covered by the new grant.
Retroactive sign-off is opt-in follow-up, not blocked by the
workflow being in place.
@rumblefrog rumblefrog added this pull request to the merge queue May 14, 2026
Merged via the queue into main with commit 8158755 May 14, 2026
@rumblefrog rumblefrog deleted the feat/web-panel-cla branch May 14, 2026 22:13
@github-actions github-actions Bot locked and limited conversation to collaborators May 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant