Full auto pipeline for simple releases your packages.
- Collect git history for auto release
- Use Conventional Commits for commit guidelines
- Generate CHANGELOG.md
- Update package.json, package-lock.json, npm-shrinkwrap.json
- Parse body commits as Markdown, support utf-8 and emoji 🚀
- Commit, tag and push new version
- Upload release on Github / Gitlab
- Upload package on Github / Npmjs.org
- Workspace / monorepo support (npm, yarn, pnpm, bun)
- Auto-detect package manager for publish
- Lifecycle scripts support (preversion, version, postversion)
- Zero dependencies
npm i @askuzminov/simple-releaseSetup initial version in package.json before first release:
| Start with | fix → | feat → | break → |
|---|---|---|---|
"version": "0.0.0" |
0.0.1 |
0.1.0 |
1.0.0 |
"version": "0.0.0-0" |
0.0.0 |
0.0.0 |
0.0.0 |
"version": "1.0.0-0" |
1.0.0 |
1.0.0 |
1.0.0 |
"scripts": {
"release": "simple-release"
}npm run release| Command | Description |
|---|---|
help |
Get command list |
prerelease |
Only up version, no git changes and release |
prerelease=ID |
Only up version with custom prerelease ID |
enable-prerelease |
Force full process for prerelease |
disable-push |
Prevent git push |
disable-git |
Prevent git commit and tag |
disable-md |
Prevent write CHANGELOG.md |
disable-github |
Prevent Github / Gitlab release |
dry-run |
Show what would happen without making changes |
verbose |
Show detailed output (commits, changelog preview) |
provenance |
Generate provenance attestation when publishing |
# Release without git push
simple-release disable-push publish-npmjs
# Only bump version, no git, no publish
simple-release disable-git disable-github
# Preview what would happen
simple-release dry-run
# Detailed output
simple-release verbose publish-npmjs| Command | Description |
|---|---|
publish-github |
Publish in Github registry |
publish-npmjs |
Publish in Npmjs registry |
--publish-custom URL |
Publish in custom registry |
simple-release publish-github publish-npmjs
simple-release --publish-custom https://your_domain/npm/ --publish-custom https://other_domain/npm/
# Publish to all registries at once
simple-release publish-github publish-npmjs --publish-custom https://your_domain/npm/simple-release --mode publish # Default
simple-release --mode current-version # Return current version
simple-release --mode next-version # Return next version
simple-release --mode has-changes # Return true | falseUsage in scripts:
# Get current version
VERSION=$(simple-release --mode current-version)
# Conditional release
if [ "$(simple-release --mode has-changes)" = "true" ]; then
simple-release publish-npmjs
fi# Prerelease with auto ID: 1.2.3 → 1.2.4-pre.0
simple-release prerelease
# Prerelease with custom ID: 1.2.3 → 1.2.4-beta.0
simple-release prerelease=beta
# Full release process for prerelease (git, changelog, publish)
simple-release enable-prerelease prerelease=beta publish-npmjs-
--match - Match only needed tags in git history
Using glob(7)
simple-release --match 'v[0-9]*' simple-release --match='v[0-9]*'
-
--file - Filter files for include/exclude
By default, all files are included except those described in
.gitignoreInclude:
- folder
- folder/file
- folder/*.css
Exclude:
- :!folder
- :!folder/*file
- :(exclude)folder
- :(exclude,icase)SUB
simple-release --file src --file types --file 'folder/*.css' --file ':!dist' simple-release --file=src --file=types --file='folder/*.css' --file=':!dist'
-
--version - Custom format for version, default
v{VERSION}simple-release --version v{VERSION} simple-release --version=v{VERSION} simple-release --version @my-org/my-lib@{VERSION} -
--source-repo - Custom path to links for sourcecode
Default from
package.json:repository.urlsimple-release --source-repo myorg/somepackage simple-release --source-repo https://github.com/askuzminov/simple-release simple-release --source-repo https://github.com/askuzminov/simple-release.git
-
--release-repo - Custom path to links for release notes
Default from
package.json:repository.urlsimple-release --release-repo myorg/somepackage simple-release --release-repo https://github.com/askuzminov/simple-release simple-release --release-repo https://github.com/askuzminov/simple-release.git
Workspaces are auto-detected from:
package.jsonworkspacesfield (npm, yarn, bun)pnpm-workspace.yaml(pnpm)
When workspaces are detected, simple-release will:
- Discover all packages
- Detect changes per package (git log scoped to package directory)
- Bump versions independently for changed packages
- Update cross-package dependencies
- Create a single git commit with all version bumps
- Create separate git tags per package (
@org/pkg@1.2.0) - Push once
- Create releases and publish for each changed package
| Command | Description |
|---|---|
no-workspace |
Force single-package mode even in a monorepo |
--workspace NAME |
Select specific packages |
--contents DIR |
Publish from subdirectory (e.g. dist) |
--cascade MODE |
Cross-package dependency updates |
| Mode | Behavior | Best for |
|---|---|---|
full (default) |
Always bump + publish dependents | Enterprise, strict CI, npm registry consistency |
lazy |
Bump only when range doesn't cover new version | Libraries with semver ranges, fewer releases |
none |
Only release packages with actual code changes | Manual control, independent teams |
devDependencies and peerDependencies are never cascaded in any mode.
When @org/core@1.1.0 is released:
@org/appdepends on"@org/core": "^1.0.0"→ update to"^1.1.0"+ patch bump + publish@org/appdepends on"@org/core": "workspace:*"→ patch bump + publish (PM resolves version)- Always guarantees npm registry has the latest dependency versions
When @org/core@1.1.0 is released:
@org/appdepends on"@org/core": "^1.0.0"→ skip (^1.0.0already covers1.1.0)@org/appdepends on"@org/core": "~1.0.0"→ bump (~1.0.0doesn't cover1.1.0)@org/appdepends on"@org/core": "1.0.0"→ bump (exact, doesn't cover1.1.0)@org/appdepends on"@org/core": "workspace:*"→ bump (exact, always broken)@org/appdepends on"@org/core": "workspace:^"→ skip (resolves to^1.0.0, covers1.1.0)@org/appdepends on"@org/core": "workspace:~"→ bump (resolves to~1.0.0, doesn't cover1.1.0)
When @org/core@2.0.0 (major) is released:
@org/appdepends on"@org/core": "^1.0.0"→ bump (^1.0.0doesn't cover2.0.0)@org/appdepends on"@org/core": "workspace:^"→ bump (resolves to^1.0.0, doesn't cover2.0.0)
- Only packages with actual git changes are released
- Cross-package dependencies are not updated
- Use when each team owns their package and manages deps manually
Do your packages have consumers outside the monorepo (published to npm)?
├─ Yes
│ Do you use semver ranges (^, ~) between packages?
│ ├─ Yes → lazy (fewer releases, ranges handle compatibility)
│ └─ No (exact or workspace:*) → full (always keep npm in sync)
└─ No (internal only / private packages)
└─ none (no need to publish dependents)
npm / yarn / bun:
my-monorepo/
package.json # { "workspaces": ["packages/*"] }
packages/
core/
package.json # { "name": "@org/core", "version": "1.0.0" }
utils/
package.json # { "name": "@org/utils", "version": "2.0.0" }
pnpm:
my-monorepo/
package.json
pnpm-workspace.yaml # packages: \n - 'packages/*'
packages/
core/
package.json # { "name": "@org/core", "version": "1.0.0" }
utils/
package.json # { "name": "@org/utils", "version": "2.0.0" }
# Release all changed packages
simple-release publish-npmjs
# Release specific packages only
simple-release --workspace @org/core publish-npmjs
# Publish from dist/ subdirectory
simple-release --contents dist publish-npmjs
# Disable cascade
simple-release --cascade none publish-npmjsThe package manager is auto-detected by lockfile:
| Lockfile | Package Manager |
|---|---|
| package-lock.json / npm-shrinkwrap.json | npm |
| bun.lock / bun.lockb | bun |
| pnpm-lock.yaml | pnpm |
| yarn.lock | yarn |
The detected PM is used for publish. All other operations (version bump, lifecycle scripts, git) are PM-independent.
Registry is passed via
--registryflag (npm, pnpm, bun) orYARN_REGISTRYenv var (yarn). Multi-registry publishing works with all package managers.
| Method | Token lifetime | 2FA | Best for |
|---|---|---|---|
| Granular Access Token | Up to 90 days | Bypass 2FA | CI with token rotation |
| OIDC Trusted Publishing | Per-job (no token) | Not needed | GitHub Actions / GitLab CI |
Classic npm tokens were revoked in December 2025. Use granular tokens or OIDC instead.
- Create token at npmjs.com/settings/~/tokens
- Set permissions: Read and write, select packages, enable Bypass 2FA
- Add to CI secrets as
NPM_TOKEN
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> ~/.npmrc
simple-release publish-npmjsSetup on npmjs.com: Package → Settings → Trusted publishing → GitHub Actions (specify repo and workflow file). Then:
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- run: npx @askuzminov/simple-release publish-npmjsProvenance attestations are generated automatically with OIDC — no provenance flag needed.
OIDC requires npm >= 11.5.1. Node 24+ includes it. Node 22 ships with npm 10 — upgrade npm or use Node 24.
No npmjs.org setup needed. Use provenance flag with a granular token:
permissions:
contents: write
id-token: write # Required for provenance
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- run: npx @askuzminov/simple-release publish-npmjs provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}Note: Provenance and OIDC apply only to npmjs.org. GitHub Packages and GitLab registries use their own auth (
GITHUB_TOKEN,CI_JOB_TOKEN) and are not affected by these changes.
Lifecycle scripts from package.json are executed in this order:
preversion- before version bump (e.g. run tests)- Version is written to package.json + lockfiles
version- after version bump (e.g. build)- Git commit, tag, push
postversion- after git operations (e.g. cleanup)
Scripts are executed via shell directly, not through a package manager. The npm_package_version environment variable is set to the new version.
"scripts": {
"preversion": "npm test",
"version": "npm run build",
"postversion": "echo Released!"
}Check commit message with husky:
Husky v9+ (.husky/commit-msg):
simple-release-lint $1Husky v4 (package.json):
"husky": {
"hooks": {
"commit-msg": "simple-release-lint"
}
}<type>: <description>- simple variant<type>(scope): <description>- with some scope<type>!: <description>- breaking change<type>(scope)!: <description>- breaking change with scope
Example with body:
feat(ABC-123): New solution
- Add [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- **Some** *specs* added...
Example with breaking change:
refactor(core): Migrate on new solution
BREAKING CHANGES: should upgrade version
Some specs...
| Type | Bump | Description |
|---|---|---|
| break | MAJOR |
Breaking changes |
| feat | MINOR |
Features |
| build | PATCH |
Build system or external dependencies |
| chore | PATCH |
Chore |
| ci | PATCH |
Continuous Integration |
| docs | PATCH |
Documentation |
| fix | PATCH |
Bug Fixes |
| perf | PATCH |
Performance |
| refactor | PATCH |
Refactoring |
| revert | PATCH |
Revert code |
| style | PATCH |
Styles and formatting |
| test | PATCH |
Tests |
For MAJOR can be used ! (example refactor!: new lib).
For MAJOR also can be used BREAKING CHANGES: or BREAKING CHANGE: in description of commit.
- Merge pull request
- Merge remote-tracking branch
- Automatic merge
- Auto-merged ... in ...
- Auto-merged ... into ...
- Merged ... in ...
- Merged ... into ...
- Merge branch
- Revert
- revert
- fixup
- squash
Instead of repeating CLI flags, configure defaults in package.json:
{
"simple-release": {
"contents": "dist",
"cascade": "full"
}
}CLI flags always override config values.
| Code | Meaning |
|---|---|
0 |
Success (or no changes found) |
1 |
Error (git failure, script failure, publish failure) |
--mode has-changes returns exit code 0 in both cases — use the stdout output (true/false) to determine result.
git log → parse conventional commits → calculate version bump
↓
preversion script → bump package.json + lockfiles → version script
↓
generate CHANGELOG.md
↓
git add → git commit → git tag → git push
↓
postversion script → github/gitlab release → npm publish
Single package: one commit + one tag
commit: chore(release): v1.2.3 [skip ci]
tag: v1.2.3
Monorepo: one commit + tag per changed package
commit: chore(release): publish [skip ci]
- @org/core@1.2.0
- @org/utils@3.1.0
tags: @org/core@1.2.0
@org/utils@3.1.0
# Changelog
All notable changes to this project will be documented in this file. See [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit guidelines.
## [v1.2.0](https://github.com/user/repo/compare/v1.1.0...v1.2.0) (2026-04-10)
### Features
- **auth**: add OAuth2 support ([abc1234](https://github.com/user/repo/commit/abc1234...))
- new dashboard page ([def5678](https://github.com/user/repo/commit/def5678...))
### Bug Fixes
- **api**: fix rate limiting ([fed8765](https://github.com/user/repo/commit/fed8765...))| Variable | Required | Description |
|---|---|---|
GH_TOKEN |
For releases | Github token (PAT or GITHUB_TOKEN) |
GITHUB_SERVER_URL |
No | Default: https://github.com |
GITHUB_REPOSITORY |
No | Fallback repo (e.g. user/repo) |
GITHUB_TOKEN (native) works if workflow has permissions: contents: write.
For protected branches with required reviews, GITHUB_TOKEN cannot push directly. Options:
| Approach | Pros | Cons |
|---|---|---|
| GitHub App (recommended) | Bypass branch protection, reusable across repos, no personal account | One-time setup |
| PAT (Fine-grained) | Simple setup | Tied to personal account, max 1 year expiry |
disable-push + PR |
Works with GITHUB_TOKEN |
Requires manual merge of release PR |
| Deploy key with write access | No personal account needed | Cannot create GitHub Releases via API |
One-time setup, works across all your repos:
1. Create App:
GitHub → Settings → Developer settings → GitHub Apps → New
- App name:
simple-release-bot - Webhook: uncheck Active
- Permissions:
- Repository → Contents: Read and write (git push, tags, releases)
- Repository → Metadata: Read-only (required)
- Where can this app be installed: Only on this account
2. Install App:
App page → Install App → select repos (all or specific)
If you add new permissions later, go to Installation → Accept new permissions to apply them.
3. Generate private key:
App page → General → Private keys → Generate a private key → save .pem file
4. Add secrets to each repo (or use gh CLI for bulk):
# Get App ID from app page → General → About
APP_ID=123456
# Add to all repos at once
for repo in my-repo-1 my-repo-2 my-repo-3; do
gh secret set APP_ID --repo yourname/$repo --body "$APP_ID"
gh secret set APP_PRIVATE_KEY --repo yourname/$repo < app-private-key.pem
done5. Allow bypass in branch protection:
Repo → Settings → Branches → Edit rule → Allow specified actors to bypass → add your App
6. Workflow (copy to any repo):
- name: Generate App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}Use ${{ steps.app-token.outputs.token }} as GH_TOKEN for releases. For GitHub Packages publish, use ${{ github.token }} (App tokens cannot publish packages).
| Variable | Required | Description |
|---|---|---|
CI_JOB_TOKEN |
For releases | Gitlab job token |
CI_SERVER_HOST |
For releases | Gitlab domain |
CI_PROJECT_ID |
For releases | Gitlab project ID |
CI_JOB_ID |
Auto | Presence triggers Gitlab mode |
CI_SERVER_URL |
No | Gitlab server URL |
CI_PROJECT_NAMESPACE |
No | Fallback namespace |
CI_PROJECT_NAME |
No | Fallback project name |
Gitlab is auto-detected when
CI_JOB_IDis set (present in all Gitlab CI pipelines).
CI_JOB_TOKEN inherits permissions of the user who triggered the pipeline. For protected branches, use a Group/Project Access Token with Maintainer role (see Gitlab CI example).
First release (no tags exist): Full git history from initial commit is used. All commits will appear in the first CHANGELOG entry.
No changes detected: Nothing happens — no version bump, no commit, no publish. Exit code 0.
Prerelease to release transition:
1.0.0 → prerelease=beta → 1.0.1-beta.0 → prerelease=beta → 1.0.1-beta.1 → (release) → 1.0.1
Multiple breaking changes: Only one major bump per release, regardless of how many breaking commits.
Unknown commit types:
Commits that don't match any known type (e.g. update: something) are grouped under "Others changes" with a patch bump.
Empty commit body: Supported — only the title line is required.
[skip ci] in release commit:
Added automatically to prevent CI loops: chore(release): v1.2.3 [skip ci]
package-lock.json missing:
Silently skipped — works fine without lockfiles.
Monorepo package without changes: Skipped entirely — no bump, no tag, no publish for unchanged packages.
Lifecycle script fails: Process stops immediately. No git commit, no publish. Fix the issue and run again.
Git push fails:
Tags and commits are created locally but not pushed. Run git push && git push --tags manually after fixing.
Publish partially fails (git already pushed):
Re-running the workflow won't help — no changes detected after [skip ci] commit. Publish failed packages manually:
# Check which version was released
git log --oneline -1
# Publish manually to the failed registry
cd dist # if using --contents
npm publish --registry https://registry.npmjs.org --tag latestGitHub Release not created (git already pushed): Create release manually on GitHub → Releases → Draft new release → select existing tag.
- Node.js >= 10.12 (or Bun)
- Git
- Works on Linux, macOS, Windows
| simple-release | lerna (9+) | changesets | semantic-release | |
|---|---|---|---|---|
| Dependencies | 0 | 50+ (requires Nx) | 20+ | 30+ |
| Setup | 1 line | lerna.json + nx.json | Config files | Plugins |
| Monorepo | Built-in | Built-in | Built-in | Plugin |
| Independent versioning | Built-in | Built-in | Built-in | Plugin |
| Topological sort | Built-in | Built-in | No | No |
| Cross-package cascade | full / lazy / none | Full only | Full only | No |
| Conventional commits | Built-in | Built-in | Manual | Plugin |
| Commit lint | Built-in | commitlint | commitlint | commitlint |
| Changelog | Built-in | Built-in | Built-in | Plugin |
| Github + Gitlab | Built-in | Github only | Github only | Plugin |
| npm / bun / pnpm / yarn | All built-in | npm | npm / pnpm / yarn | npm |
| Lifecycle scripts | Built-in (PM-free) | Via npm | No | No |
| Prerelease / canary | Built-in | Built-in | Built-in | Plugin |
| Provenance / OIDC | Built-in | v9+ | Via npm | Plugin |
| Multiple registries | Built-in | One at a time | One at a time | One at a time |
| Publish from subdirectory | --contents |
contents |
No | No |
| Node.js | >= 10.12 | >= 20.19 | >= 18 | >= 18 |
{
"name": "@org/monorepo",
+ "workspaces": ["packages/*"],
"devDependencies": {
- "lerna": "^6.0.0",
+ "@askuzminov/simple-release": "^1"
},
"scripts": {
- "lerna:publish": "lerna publish --create-release github",
- "lerna:canary": "lerna publish --canary --amend --allow-branch feature/*"
+ "release": "simple-release --contents dist publish-github",
+ "release:canary": "simple-release --contents dist publish-github prerelease=$BRANCH_NAME.$BUILD_ID"
}
}.husky/commit-msg:
-npx commitlint --edit $1
+simple-release-lint $1Remove commitlint and @commitlint/* from devDependencies.
rm lerna.json| lerna.json | simple-release | Notes |
|---|---|---|
"version": "independent" |
Default | Always independent |
"conventionalCommits": true |
Default | Always conventional commits |
"contents": "dist" |
--contents dist |
Publish from subdirectory |
"registry": "https://npm.pkg.github.com" |
publish-github |
Or --publish-custom URL |
"createRelease": "github" |
Default | Always creates release when GH_TOKEN set |
"message": "chore(release): publish [skip ci]" |
Default | Same format built-in |
"ignoreChanges": ["**/*.spec.ts"] |
--file ':!**/*.spec.ts' |
Git pathspec |
"allowBranch": ["master"] |
CI-level | Run release only on master in CI |
lerna publish --canary --preid=ID |
prerelease=ID |
Canary releases |
lerna run build |
npm run build -ws or "version": "npm run build" |
Via npm workspaces or lifecycle |
# Production release
-npm run lerna:publish
+npm run release
# Canary release
-npm run lerna:canary
+npm run release:canaryLerna updates cross-package deps automatically. simple-release does the same:
--cascade full(default) — always bump + publish dependents (like lerna)--cascade lazy— bump only when range doesn't cover new version--cascade none— manual management
If some packages were excluded from lerna.json, use --workspace to select specific packages:
# Release only specific packages
simple-release --workspace @org/core --workspace @org/utils --contents dist publish-githubFull example with GitHub App + OIDC (recommended):
name: Release
on:
push:
branches: [master, feature/*]
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
jobs:
release:
name: Release
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'skip ci')"
permissions:
contents: write
packages: write
id-token: write
steps:
- name: Generate App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 24
- name: Setup NPM
run: echo '//npm.pkg.github.com/:_authToken=${{ steps.app-token.outputs.token }}' >> ~/.npmrc
- name: Setup GIT
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
mkdir -p ~/.ssh
ssh-keyscan github.com > ~/.ssh/known_hosts
- name: Install dependencies
run: npm ci
- name: Check
run: |
npm run check-types
npm run lint
- name: Test
run: npm test
- name: Build
run: npm run build
- name: Release
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
BRANCH_NAME: # set via your branch detection step
BUILD_ID: # set via your build ID step
run: |
if [[ $BRANCH_NAME == 'master' ]]; then
npm run release -- publish-github publish-npmjs provenance
else
npm run release -- publish-github prerelease=$BRANCH_NAME.$BUILD_ID
fiUsing the action:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: askuzminov/simple-release@v1
with:
args: 'publish-npmjs publish-github'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}Minimal example with npx (no protected branch push):
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-node@v4
with: { node-version: 24 }
- run: npx @askuzminov/simple-release publish-npmjs provenance
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}git config --global push.default current
git config --local user.email "bot@ci.com"
git config --local user.name "CI"
mkdir -p ~/.ssh
ssh-keyscan github.com > ~/.ssh/known_hostsAdd .npmrc to .gitignore.
Setup .gitlab-ci.yml:
image: node:24
stages:
- publish
deploy:
stage: publish
only:
- branches
variables:
# Setup group or project access token with role "Maintainer"
# https://docs.gitlab.com/ee/user/group/settings/group_access_tokens.html
CI_JOB_TOKEN: $CI_TOKEN
# Setup strategy for clean history
GIT_STRATEGY: clone
# Setup depth for full history
GIT_DEPTH: 0
script:
- |
# Setup GIT
git config --local user.email "ci@example.com"
git config --local user.name "ci"
# Allow ci to push branch
git remote set-url origin "https://ci:$CI_JOB_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME.git"
# Avoid problem with detached branch
git checkout "$CI_COMMIT_REF_NAME"
- |
# Setup .npmrc
echo "//$CI_SERVER_HOST/api/v4/projects/$CI_PROJECT_ID/packages/npm/:_authToken=$CI_JOB_TOKEN" > .npmrc
echo "@$CI_PROJECT_NAMESPACE:registry=https://$CI_SERVER_HOST/api/v4/projects/$CI_PROJECT_ID/packages/npm/" >> .npmrc
- |
# Prepare your package
npm ci
npm run lint
npm test
- |
if [[ $CI_COMMIT_REF_NAME == 'master' ]]; then
npm run release -- --publish-custom "https://${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/"
else
npm run release -- --publish-custom "https://${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/" prerelease=$CI_COMMIT_REF_SLUG.$CI_JOB_ID
fi