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").
Live previews
The "Preview" tabs of the component pages call real services from the
reader's browser, without a login. Their endpoints, and the IDs of the
objects that single-object previews show, are set in one place:
apps/documentation/utils/endpoints.ts. Each value can be overridden at
build time (also with npm run dev) with an environment variable:
| Variable | Used by | Default |
|---|---|---|
NEXT_PUBLIC_SERVICE_REGISTRY_URL | Service Registry previews | public instance |
NEXT_PUBLIC_CLOUD_REGISTRY_URL | Cloud Registry previews | public instance |
NEXT_PUBLIC_TRS_URL | TRS previews | public instance |
NEXT_PUBLIC_TRS_FILER_URL | TRS-Filer previews | none |
NEXT_PUBLIC_WES_URL | WES previews | none |
NEXT_PUBLIC_SERVICE_ID | Service Registry "Service" preview | placeholder |
NEXT_PUBLIC_TRS_TOOL_ID | TRS "Tool" preview | a tool of the public instance |
NEXT_PUBLIC_WES_RUN_ID | WES "Run" preview | placeholder |
What works with the defaults:
- Service Registry and TRS: the previews read from public instances. The
"Service" preview shows an error until
NEXT_PUBLIC_SERVICE_IDnames a registered service. - Cloud Registry: the form loads its options, but creating a service needs a login, so submitting fails.
- WES and TRS-Filer: there is no public instance that works without a
login, so these previews show a notice instead. To try them, run your own
instance and set its endpoint, e.g.
NEXT_PUBLIC_WES_URL=https://wes.example.com/ga4gh/wes/v1 npm run devinapps/documentation/.
An endpoint must allow anonymous requests and cross-origin requests (CORS) from the site that serves the documentation. Services usually allow only known origins, so previews may fail on other origins, e.g. on the preview builds of pull requests.
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 tag is annotated and has a signature that GitHub verified, 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), the curated release notesdocs/releases/<version>.mdexist and are in the format below, no release of the tag (not even a draft) exists, 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 the shared actionpublish-release(opens in a new tab) of the organization (--verify-tag), with the curated notes followed by GitHub's generated notes under## Commitsand the**Full Changelog**line (a prerelease for versions such as2.0.0-alpha.49).
The curated notes, docs/releases/<version>.md, are published as written:
an intro paragraph saying what the release brings (with a link to a
migration guide if there is one), then the sections that apply, in this
order: ## Breaking changes, ## Features, ## Security, ## Fixes,
## Documentation, ## Maintenance. Sections hold bullets only, each
ending with its issue and pull request numbers. Links must be absolute
(https://…), and the file must not contain TODO or FIXME, nor a
## Commits section or a **Full Changelog** line, which the action adds.
The action's
README (opens in a new tab)
has the complete rules. For example:
This release adds the run outputs view to the WES components.
## Features
- Show the outputs of a run (#12, #34)
## Fixes
- Keep the run list after a provider change (#56, #78)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. Add the curated notesdocs/releases/<version>.md(see above). 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>(with a key registered with your GitHub account, so that GitHub verifies the signature), 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.
If only "Publish release" fails, fix the cause and use "Re-run failed
jobs" (not "Re-run all jobs": prepare fails once a release of the tag
exists); delete a draft release of the tag first, if there is one. A
re-run passes without changes if the release exists with the same curated
notes, title and prerelease flag, and fails otherwise.
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.
