Skip to content

ci: single CI gate and contribution docs - #474

Merged
uniqueg merged 32 commits into
devfrom
ci/gate-contributing
Oct 27, 2026
Merged

uniqueg merged 32 commits into
devfrom
ci/gate-contributing

Conversation

@uniqueg

@uniqueg uniqueg commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Summary

Last of the stacked pull requests for #464. Stacked on #473 (on #470): merge those first; until then this diff also shows their commits.

  • ci.yml / CI (renamed from pr_evaluation.yml / PR Evaluation), with the organization's job names: Conflict markers, Lint, Test (Node 22), Test (Node 24) and the gate CI passed, which fails unless all other jobs passed. Runs on pull requests and on pushes to dev, the default branch. Read-only token, no persisted credentials, timeouts, superseded PR runs cancelled, fail-fast: false for the test matrix. Lint also runs the tests of scripts/release.js (ci: npm trusted publishing and GitHub releases #473).

  • pr-title.yml / PR title: the Conventional Commit title check (same rules), in its own workflow, so that editing a title or description reruns only this check. Runs on pull requests to dev.

  • Changesets removed (.changeset/, @changesets/cli): its config still named main and an outdated package list; releases set versions in a version bump pull request now.

  • CONTRIBUTING.md: what's specific to this repository (PR flow against dev, main = latest release, title rules, checks, reviews, AI-assisted PRs) and the release steps in order:

    1. version bump pull request to dev (node scripts/release.js set <version>);
    2. signed tag v<version> on dev;
    3. approve the npm environment of the Release run;
    4. approve the staged versions on npmjs.com (2FA); dist-tag latest for releases and for the 2.0.0 alphas (prereleases of a major without a release yet), the prerelease identifier after that;
    5. fast-forward main to the tag.

    Plus what to do when a release fails (no re-tagging; re-run after partial staging; reject staged versions). General rules link to the org guide. The PR template's link now resolves; the README's contributing link (old org guide URL, 404) points to it.

  • .github/CODEOWNERS: * @anuragxxd.

Closes #468

Verification

Declined review findings

  • CI doesn't run when a stacked PR is retargeted (only an edited event): otherwise a push or close/reopen triggers CI. Listening to edited would rerun CI on every description edit, which this PR removes.
  • The AI-assisted PR paragraph in CONTRIBUTING.md was questioned as a new policy: it is part of the agreed contribution flow.

Maintainer steps (after merge)

  • Add CI passed and PR title (source: GitHub Actions) as required status checks to the dev ruleset, once both have reported on a PR.
  • No bypass for deploy keys is needed any more: releases push nothing.

🤖 Generated with Claude Code

Summary by Sourcery

Streamline contribution and release management around a unified CI gate, dedicated title validation, and documented repository workflows.

New Features:

  • Add a unified CI workflow with conflict detection, linting, release-script tests, supported Node.js test coverage, and a single required status gate.
  • Add a dedicated pull request title workflow enforcing the repository’s Conventional Commit title rules.
  • Add repository contribution and release guidance, including version bump, tagging, npm publishing, and recovery procedures.

Bug Fixes:

  • Correct the README contributing link to point to the repository’s contribution guide.

Enhancements:

  • Remove Changesets and its configuration and dependency in favor of versioning through release pull requests.
  • Add CODEOWNERS coverage for the repository.

CI:

  • Replace the previous pull request evaluation workflow with separate CI and pull request title workflows targeting the dev branch and its pushes.

Documentation:

  • Document repository-specific pull request practices, reviews, AI-assisted contributions, and the release process.

uniqueg and others added 12 commits October 26, 2026 15:20
Remove the changesets versioning workflow (changesets/action without a
publish input, which only added a Release check to every commit on
main), the generated .changeset/README.md and the root CHANGELOG.md
stub. changeset publish stays the publish command.

Refs #465

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The builder stage of the docs image copies the whole build context.
Send only what the build needs (allow list: workspaces, build scripts,
root manifests), so that local .env* files and other local files never
reach the image, and drop dependencies and build output within.

Closes #463

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pin every action to a full commit SHA on its current major version
(checkout v7, setup-node v7, cache v6, semantic PR title v6, ssh-agent
v0.10, push action v1.3.0 instead of master), with Dependabot keeping
the pins up to date. Replace the node_modules caches, whose key hashed a
file that doesn't exist and which used ::set-output, by the npm cache
of setup-node in CI; releases use no dependency cache. Drop the
force-with-lease input of the push action, which doesn't exist (the
input is force_with_lease) and so never had an effect.

Refs #465

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Give Dependabot pull requests a ci: prefix, so that their titles pass
the PR title check. Keep the commented-out release tests job as it was
and state the release cache comment once.

Refs #465

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ubuntu-latest now is Ubuntu 26.04, on which Playwright 1.56 can't
install its browsers, so every test job fails (unrelated to the other
changes). Pin the test job to ubuntu-24.04 until Playwright is
upgraded.

Refs #465

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Node.js 18 and 20 are end of life. Test on 22 and 24, lint and release
on 24 (npm 11, needed for trusted publishing), build the docs image on
node:24-alpine and update the development prerequisites in the README.
engines and packageManager stay as they are.

Closes #466

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename publish.yml to release.yml (Release), as in the organization's
other repositories, with job names Lint release, Bump version, Publish
packages. The publish job gets id-token: write (and only it), checks
for npm 11.5.1 or later and publishes through OIDC with provenance.
NPM_TOKEN stays as a fallback: npm tries OIDC first and uses the token
only if the exchange fails; remove it after the first OIDC release.
A new job creates a GitHub release with generated notes from the
previous version tag, as a prerelease for versions with a suffix.

Closes #467

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Order version tags by semver when looking up the previous tag for the
release notes (sort -V puts v2.0.0 before v2.0.0-alpha.1). Configure
the NPM_TOKEN fallback only right before publishing, say in the log
when it is configured, and warn about released versions without
provenance (published with the token). Name the jobs Release packages
and Release on GitHub.

Refs #467

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename pr_evaluation.yml to ci.yml (CI), as in the organization's other
repositories, with the jobs Conflict markers, Lint, Test (Node 22),
Test (Node 24) and the gate CI passed, which fails unless all of them
passed; branch rules need to require only the gate. CI also runs on
pushes to main. The PR title check moves to pr-title.yml (PR title), so
that title or description edits no longer create CI runs with all jobs
skipped. Read-only token, no persisted credentials, timeouts, and
superseded pull request runs are cancelled.

Refs #468

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add CONTRIBUTING.md, which the PR template and the README link: the
pull request flow (branch off main, Conventional Commit titles, squash
merge, checks, reviews, no changesets, AI-assisted pull requests) and
the release flow (lockstep versions, tag on main, Release workflow with
trusted publishing and GitHub releases, frozen packages). Point the
README to it instead of the org guide's old URL, which is gone.

Refs #468

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Request reviews from the maintainer automatically.

Closes #468

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use the issue keyword of the PR template, mention direct pushes by
maintainers, drop the documentation preview (none is posted by this
repository), say what frozen packages means and that an npm token
remains as a fallback for now. Install dependencies with npm ci in the
Lint job, as in the other jobs.

Refs #468

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Oct 26, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 1279b73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
elixir-cloud-components Error Error Oct 26, 2026 7:21pm UTC

@sourcery-ai

sourcery-ai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR replaces the prior PR-evaluation setup with a single, security-conscious CI workflow and explicit CI passed gate, isolates title validation into its own check, modernizes the tag-driven release pipeline for Node 24 and npm trusted publishing, and adds repository-specific contribution, ownership, dependency-update, and runtime documentation.

Sequence diagram for pull request validation

sequenceDiagram
    actor Contributor
    participant GitHub
    participant CI
    participant PRTitle as PR title
    participant Gate as CI passed

    Contributor->>GitHub: Open or update pull request
    GitHub->>PRTitle: Run title check
    PRTitle-->>GitHub: Report PR title result
    GitHub->>CI: Run CI workflow
    CI->>CI: Run Conflict markers
    CI->>CI: Run Lint
    CI->>CI: Run Test Node 22 and 24
    CI->>Gate: Check all job results
    Gate-->>GitHub: Report CI passed result
Loading

Sequence diagram for tag-driven release

sequenceDiagram
    actor Maintainer
    participant GitHub
    participant Release
    participant Main
    participant NPM

    Maintainer->>GitHub: Push version tag on main
    GitHub->>Release: Start Release workflow
    Release->>Release: Run lint
    Release->>Main: Commit and push version bump
    Release->>NPM: Publish packages with OIDC trusted publishing
    NPM-->>Release: Return publication and provenance status
    Release->>GitHub: Create GitHub release
Loading

File-Level Changes

Change Details Files
Consolidates pull-request and main-branch validation into a single CI workflow with an explicit aggregate gate.
  • Renames and restructures the existing evaluation workflow around conflict detection, linting, Node 22/24 test matrix jobs, and the required CI passed result.
  • Adds least-privilege permissions, pinned actions, credential-free checkouts, timeouts, concurrency cancellation, dependency/browser caching, and non-fast-failing matrix execution.
  • Ensures the aggregate gate fails for any failed, cancelled, or skipped prerequisite job.
.github/workflows/ci.yml
.github/workflows/pr_evaluation.yml
Separates Conventional Commit title validation from the general CI workflow.
  • Adds a dedicated PR title workflow that runs on relevant pull-request lifecycle and edit events.
  • Preserves the allowed commit types and enforces lowercase subjects with a 50-character limit.
.github/workflows/pr-title.yml
Updates release automation for the documented tag-driven release process and stronger publishing security.
  • Renames the workflow and jobs, upgrades runtime/action pins to Node 24-era versions, and disables release dependency caching.
  • Uses npm trusted publishing with OIDC and provenance checks, retaining a temporary token fallback.
  • Keeps version bumping, package publication, and GitHub release creation as dependent stages, including generated notes and prerelease handling.
.github/workflows/publish.yml
.github/workflows/release.yml
Documents repository-specific contribution and release procedures and aligns repository links and runtime requirements.
  • Adds contribution guidance covering issue-first PRs, title/check requirements, reviews, AI-assisted PRs, no changesets, and frozen packages.
  • Documents tag-based releases, deploy-key bump pushes, trusted publishing, and the no-retag policy.
  • Updates README Node requirements and contributing link, and removes obsolete changeset/changelog files.
CONTRIBUTING.md
README.md
.changeset/README.md
CHANGELOG.md
Adds repository maintenance and ownership configuration.
  • Assigns all files to the repository code owner.
  • Configures monthly grouped Dependabot updates for GitHub Actions with Conventional Commit-style titles.
  • Adds Docker ignore rules and updates the Docker base image to Node 24.
.github/CODEOWNERS
.github/dependabot.yml
.dockerignore
Dockerfile

Assessment against linked issues

Issue Objective Addressed Explanation
#468 Provide a single required CI gate on pull requests and pushes to main, and run the PR title check in a separate workflow so title or body edits do not rerun CI. ✅
#468 Document repository contribution and release flows, including trusted publishing, and ensure the README and PR template link to CONTRIBUTING.md. ✅
#468 Configure code owners so they are automatically requested for review. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@uniqueg
uniqueg marked this pull request as ready for review October 26, 2026 18:50

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".github/workflows/ci.yml" line_range="35" />
<code_context>
+        with:
+          persist-credentials: false
+      - name: List files with merge conflict markers
+        run: git --no-pager grep "<<<<<<<" ":(exclude).github/" || true
+      - name: Fail or succeed job if any files with merge conflict markers have been checked in
+        # Find lines containing "<<<<<<<", then count the number of lines.
</code_context>
<issue_to_address>
**Conflict markers pass CI**

When a conflict marker is checked into a `.github/` file, or the number of matching lines outside `.github/` is a positive multiple of 256, `git grep` excludes `.github/`, and `exit $(... | wc --lines)` truncates a positive multiple of 256 to status 0. The conflict job succeeds and CI reports green despite checked-in conflict markers.

Scan files under `.github/` too, and make the job fail whenever the match count is nonzero without using that count as an exit status.

Also at `.github/workflows/ci.yml:39`.
</issue_to_address>

### Comment 2
<location path=".github/dependabot.yml" line_range="9" />
<code_context>
+    directory: /
+    # Pull request titles must be Conventional Commits (PR title check)
+    commit-message:
+      prefix: ci
+    schedule:
+      interval: monthly
</code_context>
<issue_to_address>
**Dependabot PRs fail title checks**

When dependabot opens an update pull request with its generated `Bump ...` subject, or a grouped Actions-update subject exceeds 50 characters, the `ci` prefix leaves the generated subject starting with uppercase `Bump`, which the required PR-title check rejects; grouped Actions-update subjects can also exceed its 50-character limit. Dependabot update PRs cannot pass the required check without manual title edits.

Configure Dependabot-generated titles or the PR-title check so those titles satisfy the required format and length.

Also at `.github/workflows/pr-title.yml:44`.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 2 findings to address first, and if the changed release workflow builds or selects the wrong package contents, it can publish them to npm under a version that cannot be published again; reverting the workflow would not retract that release from users or downstream consumers. The CI and documentation changes are otherwise reversible.

Blocking findings: .github/workflows/ci.yml:35, .github/dependabot.yml:9


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/dependabot.yml
Fail the conflict marker check on any match instead of using the match
count as exit status (a multiple of 256 passed). Skip the PR title
check for Dependabot, whose titles can't be configured to fit the
lowercase and 50-character rules; a skipped job passes branch rules.

Refs #468

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
uniqueg and others added 10 commits October 27, 2026 02:28
Add scripts/release.js, which sets and checks the shared version of the
root and of all public packages in packages/*, prints their dist-tag and
pins their internal dependencies for publishing (with tests).

@elixir-cloud/tes is deprecated (no build, so a release would have no
code): mark it private, so that it is no longer released. Give
@elixir-cloud/eslint-config a repository URL for provenance. Drop the
unused `release` script (changeset publish).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rework release.yml for the branch model of the other repositories: the
version bump is a pull request to `dev`, a maintainer tags `v<version>`
on `dev`, and the workflow builds from the tag and pushes nothing (no
bump job, no deploy key). It checks that all package versions match the
tag and that the tag is on the default branch before anything else.

The publish job runs in the `npm` environment and stages each public
package with `npm stage publish --provenance --tag <dist-tag>` (trusted
publishing; npm 11.15.0 or later); maintainers approve the staged
versions on npmjs.com. The NPM_TOKEN fallback and the provenance check
are gone. Outside the main repository, staging is a dry run.

PR Evaluation now runs on pull requests to `dev`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`dev` is the default branch now and `main` points at the latest
release: run CI on pushes and pull requests to `dev`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Releases set versions in a version bump pull request and no longer use
changesets: remove .changeset/ (its config still named `main` and an
outdated package list) and @changesets/cli.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the review: check out the tagged commit (github.sha) in all jobs,
check the tag against `dev`, fail if the package list is empty or an
npm lookup fails for another reason than "not found", and warn in the
summary not to approve versions while others failed to stage. Test the
command line of scripts/release.js and clean up test fixtures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep Node.js 24 (and 22/24 in the test matrix) in the conflicting
setup-node steps, and run PR Evaluation on pull requests to `dev`, the
default branch now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the second review: `npm view` doesn't see staged versions, so a
re-run tried to stage them again and failed on the conflict (E409)
forever. Count those as staged (the same commit, as tags are
immutable), keep stdin away from npm in the loop, and say in the
header that tags must be on `dev`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
uniqueg and others added 3 commits October 27, 2026 03:20
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run node --test scripts/release.test.js in the lint job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`dev` is the development branch and `main` the latest release. Releases
go: version bump pull request (scripts/release.js set), signed tag on
`dev`, approval of the `npm` environment, approval of the staged
versions on npm, fast-forward of `main`. Also describe the dist-tags and
how to recover from failed staging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
uniqueg and others added 6 commits October 27, 2026 03:55
Decided by the maintainer: as before, the 2.0.0 alphas go to `latest`.
Prereleases of a major version without a release yet (no tag
v<major>.x.y without suffix) get `latest`; once the major is released,
prereleases get their identifier (`rc` for 2.1.0-rc.1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the review: without any release tag (e.g. a clone without tags),
every prerelease would get `latest`. Fail instead, also in the workflow
(the dist-tag is no longer computed inside `echo`), wrap git errors, and
tidy the tests and comments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

@uniqueg
uniqueg merged commit 00d817e into dev Oct 27, 2026
8 of 9 checks passed
@uniqueg
uniqueg deleted the ci/gate-contributing branch October 27, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: single CI gate and contribution docs

1 participant