- appium@3.7.0 - @appium/base-driver@10.8.0 - @appium/base-plugin@3.3.4 - @appium/docutils@3.0.0 - @appium/driver-test-support@3.0.0 - @appium/eslint-config-appium-ts@3.2.5 - @appium/execute-driver-plugin@7.0.0 - @appium/fake-driver@6.2.3 - @appium/fake-plugin@4.4.0 - @appium/images-plugin@5.0.0 - @appium/logger@2.0.11 - @appium/opencv@5.0.0 - @appium/oxc-config@1.1.1 - @appium/plugin-test-support@3.0.0 - @appium/relaxed-caps-plugin@3.0.0 - @appium/semantic-release-config@1.2.0 - @appium/storage-plugin@2.0.0 - @appium/strongbox@2.0.0 - @appium/support@7.2.7 - @appium/tsconfig@1.2.1 - @appium/types@1.7.0 - @appium/universal-xml-plugin@3.0.0
@appium/semantic-release-config
Shared
semantic-releaseconfiguration factory for Appium and Appium-adjacent projects.
Usage
Install the package:
npm install @appium/semantic-release-config --save-dev
Then, in release.config.mjs (or .releaserc.mjs):
// release.config.mjs
import releaseConfig from '@appium/semantic-release-config';
export default releaseConfig();
This reproduces the "standard" config used by most appium-org repos: an angular-preset
commit-analyzer, a conventionalcommits-preset release-notes-generator, a changelog committed
back to the repo, npm publish, and a GitHub release.
For a repo that deviates from the standard, pass options:
export default releaseConfig({
branches: ['main'],
extraGitAssets: ['npm-shrinkwrap.json'],
removeGitAssets: ['docs'],
releaseNotesTypeOverrides: {chore: {hidden: true}},
});
For a repo that isn't published to npm (a sample/demo app rather than a library), use the app
flavor:
export default releaseConfig({
flavor: 'app',
branches: ['main'],
extraGitAssets: ['app/build.gradle.kts'],
});
Options
| Option | Type | Default | Effect |
|---|---|---|---|
flavor |
'library' | 'app' |
'library' |
'app' switches to the conventionalcommits commit-analyzer preset, sets npmPublish: false, disables GitHub success/fail PR & issue comments, and defaults @semantic-release/github's assets to []. |
branches |
string[] |
(omitted) | Sets the top-level branches option. Omit to fall back to ['master'] (or semantic-release's own defaults if betaBranch is also omitted). |
betaBranch |
string |
(none) | Name of a long-lived next-major prerelease branch, e.g. 'next-major'. Appended to branches as a prerelease branch entry — see "Next-major beta branches" below. |
betaChannel |
string |
'beta' |
Prerelease identifier / npm dist-tag used for betaBranch. |
extraGitAssets |
string[] |
[] |
Appended to @semantic-release/git's assets. |
removeGitAssets |
string[] |
[] |
Removed from @semantic-release/git's assets (applied after extraGitAssets). |
githubAssets |
Array |
(flavor default) | @semantic-release/github's assets option — plain path strings or {path, label} objects. |
commitAnalyzerReleaseRules |
Array |
(flavor default) | Full override of commit-analyzer's releaseRules. |
releaseNotesTypeOverrides |
Record<string, {hidden?: boolean, section?: string}> |
(none) | Shallow-patched onto the default presetConfig.types, keyed by commit type, e.g. {chore: {hidden: true}}. |
Next-major beta branches
Some appium-org repos develop a next major version on a long-lived branch (e.g. next-major) in
parallel with normal releases off master. Pass betaBranch to have every commit on that branch —
patch, minor, or breaking alike — publish as a -beta.N prerelease instead of a stable release:
export default releaseConfig({
flavor: 'library',
betaBranch: 'next-major', // whatever your repo actually calls this branch
});
This appends {name: <betaBranch>, channel: 'beta', prerelease: 'beta'} to branches, so releases
from that branch publish to the beta npm dist-tag (npm install my-pkg@beta) as
X.0.0-beta.0, X.0.0-beta.1, etc.
How the version stays anchored: once a package's first release on that branch lands on a clean
X.0.0-beta.0 (i.e. minor and patch are both 0), semantic-release's own prerelease logic
guarantees every subsequent commit on that branch — no matter its conventional-commit type or
whether it's a breaking change — only advances the beta.N counter; it never re-bumps the major
version underneath the prerelease train. That first release is what has to land cleanly: if the
earliest commits on the branch are only patch/minor-level, the first beta versions will reflect
that lower bump and self-correct upward exactly once, the moment a genuinely breaking commit
lands — expected behavior, not a bug. Once the major is settled, it holds until the branch is
graduated to a stable release.
Don't rely on remembering to mark the first commit as breaking. semantic-release has no CLI
override to force a specific version — it's always driven by analyzing actual commits. So
deliberately land a real breaking-change commit (BREAKING CHANGE: footer or feat!:) as part of
the first PR merged after creating the beta branch, rather than depending on one showing up
naturally. If that slips, manually publishing the very first prerelease by hand (bump
package.json to X.0.0-beta.0, tag it, npm publish --tag beta) before handing off to
automated semantic-release runs works just as well — either way, what matters is that the
first release on the branch lands on a clean X.0.0-beta.0.
Gotchas
extendsin a JSON.releasercdoes a shallow merge.pluginsand other array options are replaced wholesale, not deep-merged, when redefined locally. This means a JSON config withextendscan't losslessly express "same plugin list, but tweak one nested option of one plugin" — exactly what several appium-org repos need. That's why this package ships a JS factory function instead of static JSON: the merging happens once, in JS, before semantic-release ever sees the resulting config object.- This package is ESM-only. Consumers must
importthe factory from arelease.config.mjs(or.releaserc.mjs) — repos still on CommonJS need to migrate to ESM (or at least add"type": "module") first. Also:cosmiconfig(which semantic-release uses to locate its config) searches.releaserc*files beforerelease.config.*. If a migration addsrelease.config.mjswithout deleting the old.releaserc/.releaserc.jsonin the same commit, semantic-release will silently keep using the old file.
Migrating an existing repo
This package only defines the shared config; migrating the ~26 existing appium-org repos off
their hand-copied .releaserc files is a separate, repo-by-repo effort. For each repo:
- Add
@appium/semantic-release-configas a devDependency. - Remove that repo's own
semantic-release,@semantic-release/changelog,@semantic-release/git, andconventional-changelog-conventionalcommitsdevDependencies — they're pulled in transitively via this package's own pinneddependencies, so restating their versions per-repo is no longer necessary (and would risk drifting from the versions this package actually ships). - Add a
release.config.mjsthat imports and calls the factory with whatever options reproduce that repo's current deviations (see the table above). - Delete the old
.releaserc/.releaserc.jsonin the same commit — see gotcha #2 above. - If the repo is still on CommonJS, migrate it to
"type": "module"first (or as part of the same change).
License
Copyright © 2026 OpenJS Foundation. Licensed Apache-2.0