Skip to content

Latest commit

 

History

History
87 lines (66 loc) · 7.66 KB

RELEASE.md

File metadata and controls

87 lines (66 loc) · 7.66 KB

Release Workflow

LavaMoat follows Semantic Versioning 2.0.0 and uses Conventional Commits to enable automation.

How to Publish to npm

  1. Review, approve, then merge the currently-open Release Please pull request.

    See How Releases Work for more information.

  2. Immediately after merging, checkout the main branch and pull the changes from LavaMoat/LavaMoat into your working copy.

    It is recommended you make a clean clone or use a separate local copy for publishing. Never publish from a fork. Pulling main should be a fast-forward operation; if it isn't, please start from a clean clone to be on the safe side.

  3. Assert you are logged in to the npm registry; use npm login and/or npm whoami. Do not do this on an untrusted machine.

  4. Assert your working copy has no modifications (e.g., via git status).

  5. Assert you are running Node.js v18.0.0 or later (via node --version) and npm v9.8.1 or later (via npm --version).

  6. Execute npm ci ("Clean Install"; not "Continuous Integration").

    This operation will obliterate any node_modules and packages/*/node_modules directories before installation.

  7. This step depends on whether you are publishing a new package:

    • If you are not publishing a new package, execute npm run release
    • If you are publishing a new package, execute npm run release --newPkg=<package-name>

    In both cases, Artifacts will be rebuilt and the default set of tests will run. Do not attempt to publish individual packages!

  8. Check the output of npm pack to ensure the correct files are being published.

  9. If prompted, enter your 2FA passcode or visit the URL npm provides you. Once authenticated, the publish will proceed.

  10. Verify the published package(s) on npm.

  11. For extra credit, verify the GitHub Releases.

How Releases Work

The Release Please GitHub Action automates all parts of the release process except the publish to the public npm registry.

This is the process:

  1. A contributor creates a PR targeting the main branch (main). PRs may contain changes across packages. They may not contain version bumps.

    Note: a PR will fail checks if the commit message is not in Conventional Commits format.

  2. The contributor's PR is reviewed, approved, then squashed & merged into main.

    Release Please recommends PRs are squashed instead of simply rebased. History must also be kept linear; no merge commits.

    Please also read how to represent multiple changes in a single commit message.

  3. The Release Please Action triggers, and it creates (or updates) a "release" pull request (there will only ever be one at a time); we call this the Release Please PR. The PR will contain a single commit, and its description will contain an auto-generated changelog. Release Please will also create a Draft GitHub Release for each package to be released.

    This pull request will have title "chore: main" and the label autorelease: pending. It will have been opened by user @github-actions[bot].

    Expect to see an open Release Please PR most of the time!

  4. As additional PRs from contributors are merged into main, the Release Please Action will rebase and update the Release Please PR to reflect these changes. Dependencies will be automatically bumped between packages as needed—and kept at the latest version regardless of any major version bumps.
  5. A maintainer reviews a Release Please PR, and when they are satisfied with the changes, they merge it into main. This will trigger the Release Please Action again—but this time, the GitHub Releases will come out of "draft" status and be "official". Release Please will now delete its PR branch.

    The Release Please PR does not need to be squashed, since it will only contain a single commit and be kept up-to-date with main.

  6. The maintainer must immediately publish to npm.
  7. Go to step 1.

A Note About Lifecycle Scripts

npm's ignore-scripts flag disables all lifecycle scripts for all packages. This means, for example, a prepublishOnly script will not automatically run upon an npm publish.

This is intentional. Thus, any actions that must happen pre-publish (or pre-anything) must be invoked explicitly in our package.json scripts.

This does not, however, prevent a maintainer from running npm publish without having rebuilt and tested beforehand! So: don't do that. Use npm run publish only.

Publishing, Under the Hood

If npm ignored workspaces that have already been published, we wouldn't need any extra tooling. But it does not ignore them, and instead aborts the operation. To avoid this, we need to first analyze the workspaces and query the registry for each to determine which packages have already been published. We filter those packages out of the list of packages to be published.

This "has this been published already?" query (done via npm view) will naturally fail if the package does not yet exist. Since we have no way of knowing whether it should exist--or perhaps was a typo--the maintainer must explicitly declare the names of the new, never-published packages. This is done via the --newPkg flag to npm run release, which makes its way into the publishing script.

The publishing script is located in scripts/publish.js.

Addendum: Workspace Dependency Table

folder npm name deps
aa @lavamoat/aa
allow-scripts @lavamoat/allow-scripts @lavamoat/aa
browserify lavamoat-browserify @lavamoat/aa, @lavamoat/lavapack, lavamoat-core
core lavamoat-core lavamoat-tofu
lavapack @lavamoat/lavapack lavamoat-core
node lavamoat @lavamoat/aa, lavamoat-core, lavamoat-tofu
perf lavamoat-perf lavamoat-browserify, lavamoat
preinstall-always-fail @lavamoat/preinstall-always-fail
survey survey lavamoat, lavamoat-tofu
tofu lavamoat-tofu
viz lavamoat-viz lavamoat-core
yarn-plugin-allow-scripts @lavamoat/yarn-plugin-allow-scripts