Contributing
The general rules for contributing to Cloud Components (getting started, issues, branches and pull requests, commit messages and pull request titles, pull requests prepared with AI agents) are in the contributing guide of ELIXIR On-Cloud (opens in a new tab). This page covers what is specific to this repository.
Local checks
Keep the checks green: CI passed sums up the PR title, linting, tests
(Node.js 22 and 24) and the other CI jobs. Run npm run lint,
npm run build and npm test (and
node --test scripts/release.test.js after changes to
scripts/release.js) locally before you push. CI runs the tests with
coverage (npm run test -- -- --coverage, which passes --coverage
through npm and turbo to the test runner; Chromium only; each package's
report is in its coverage/ folder) and reports it to
Codecov (opens in a new tab);
coverage of the packages with tests must not drop by more than 1 %
(codecov.yml).
Changesets are not used; versions are set in the version bump pull request of each release (see "Releases").
Releases
All public packages in packages/ (those without "private": true in
their package.json) share the version of the root package.json and are
released together (currently 2.0.0-alpha.N, until 2.0.0).
@elixir-cloud/ro-crate and the deprecated @elixir-cloud/tes are private
and not released.
The Release workflow (.github/workflows/release.yml) runs on tags
v<version> and pushes nothing to any branch. Its jobs:
prepare("Prepare release") holds all checks: the versions of the root, the released packages andCITATION.cffequal the tag's version, the release date inCITATION.cffis not in the future (UTC), the tag is ondev, theCIworkflow passed for a push of the tagged commit (if CI hasn't finished yet or failed, re-run the release once it passed), and the linters pass. The other jobs need it.npm("Release packages") builds the packages from the tag and stages them on npm with trusted publishing (opens in a new tab) (OpenID Connect, with provenance), once thenpmenvironment is approved. Staged versions become public only when a maintainer approves them on npmjs.com.publish("Publish release") creates the GitHub release for the tag, with generated notes (a prerelease for versions such as2.0.0-alpha.49).
To release <version> (e.g. 2.0.0-alpha.49), maintainers:
- Bump the version in a pull request to
dev(titlechore: release <version>): runnode scripts/release.js set <version>, which sets the version of the root and of all released packages, updatespackage-lock.json, and setsversionanddate-released(today, UTC; or--date YYYY-MM-DD, not in the future) inCITATION.cff. Commit the changes and merge the pull request once CI has passed. - Tag the merge commit on
devonce CI has passed for it (the run for the push todev), and push the tag:git tag -s v<version> -m v<version> <commit>, thengit push origin v<version>. Tags are immutable: check the commit first, e.g. withnode scripts/release.js check <version>on it, which runs the version checks of the release workflow. - Approve the
npmenvironment: the job "Release packages" of theReleaserun waits for a required reviewer of the GitHub environmentnpm(Actions → the run → "Review deployments"). - Approve the staged versions on npm: the job stages each package with
npm stage publishand lists them in the run's summary. An npm maintainer approves each one, with two-factor authentication, on the package's page on npmjs.com or withnpm stage list <package>andnpm stage approve <stage-id>. The dist-tag islatestfor releases andnextfor prereleases (e.g.2.1.0-rc.1or3.0.0-alpha.1), so thatlatestholds the newest release andnextthe prerelease published last. Until 2.0.0 (or a later release) is tagged, i.e. there is a tagv2.<minor>.<patch>or later, prereleases of 2.x (the2.0.0-alpha.Nseries) getlatestinstead; any such tag ends this, even if its release failed. A release of an older major (a backport) also getslatest, which then moves back to that older version.node scripts/release.js dist-tag <version>prints the dist-tag. The dist-tag of a staged version can't be changed, and approving it moves the dist-tag to it: approve or reject all staged versions before you tag the next version, so that an older version can't takelatestornextback. - Fast-forward
mainto the tag:git push origin v<version>^{commit}:refs/heads/main(only fast-forwards; the ruleset ofmainlets only admins update it).
A version on npm, staged or public, can't be published again, and tags
can't be moved. If a release fails before staging, fix the cause in a pull
request and release a new version. If staging fails for some packages,
don't approve any staged version yet: re-run the failed jobs of the run.
Packages already on npm are skipped, and versions staged by the earlier
attempt count as staged. If a package can't be staged at all, reject the
staged versions (npm stage reject <stage-id>) and release a new version.
Citation metadata
Cloud Components are cited with the metadata in CITATION.cff
(Citation File Format (opens in a new tab)), which
GitHub ("Cite this repository") and Zenodo use; Zenodo archives each GitHub
release with the file of the tagged commit. Its authors follow the citation metadata rule of the contributing
guide (opens in a new tab)
(not counting lock files and images). CI validates the file
(cffconvert --validate). node scripts/release.js set <version> sets its
version and date-released for each release, and the release workflow
fails if they don't match the release (see "Releases").
Documentation versions
The documentation is built on Read the
Docs (opens in a new tab) (configuration:
.readthedocs.yaml); its page "Versions"
(apps/documentation/pages/docs/versions.mdx) explains the versions to
users. latest is built from dev. Two
automation rules of the Read the Docs project activate each new tag v*
and set it as the default version, so that the newest prerelease is the
default until 2.0.0 is out. stable (the newest tag without a prerelease
suffix, built by Read the Docs) stays inactive until then.
When 2.0.0 is released, a maintainer of the Read the Docs project:
- deletes the automation rule that sets new tags
v*as the default version (the rule that activates them stays); - activates
stableand sets it as the default version (Settings → "Default version"); - enables the notification on non-stable versions (Settings → Addons →
Notifications), so that pages of
latestand of older versions point readers tostable.
