Skip to content

Release Pipeline: migrate from version-specific branches to main/development #108

Description

@jeanmachuca

Release Pipeline: migrate from version-specific branches to main/development

Repo: QuickCorp/QCObjects

Current state

The repo has version-specific branches (v2.2, v2.3, v2.4-beta, v2.4-ts, v2.5-beta) and three separate npm publish workflows (npmpublish-beta.yml, npmpublish-lts.yml, npmpublish-main.yml).

Why this change

Version-specific branches tracked different architecture waves (ECMA5, ES6+JS, full TS+JS). As the number of active tracks grew, branch-based management added complexity: CI workflows needed per-branch configuration, PR paths were unclear, and promoting a beta to LTS required manual cross-branch coordination.

What changed

  • Removed all version-specific branches (v2.2, v2.3, v2.4-beta, v2.4-ts, v2.5-beta)
  • Single active development branch: development
  • Release channel is encoded in the tag suffix, not in a branch name
  • Old version tracks preserved as archive tags

Branch model

main          ← release digest (merged from development via PR)
development   ← single active development branch
feature/*     ← topic branches, PR into development
fix/*
bugfix/*

No more version-specific branches. Every release is a tag on main.

Release channels (tags)

Tag pattern npm dist-tag Triggered by
vX.Y.Z latest consolidated npmpublish.yml
vX.Y.Z-lts lts consolidated npmpublish.yml
vX.Y.Z-beta beta consolidated npmpublish.yml
(future) -dev dev (add pattern)
(future) -alpha alpha (add pattern)

Promotion workflow

  1. Daily work on development branch
  2. v-patch --git --npm → tag vX.Y.Z-beta (beta publish)
  3. Change VERSION suffix → v-patch --git --npm → tag vX.Y.Z-lts (LTS publish)
  4. PR developmentmain → merge → tag vX.Y.Z on main (latest publish)

Branch snapshot and removal steps

Prerequisites

git fetch --all --prune

Archive old version branches

git tag archive/v2.4-beta origin/v2.4-beta
git push origin archive/v2.4-beta
git tag archive/v2.4-ts origin/v2.4-ts
git push origin archive/v2.4-ts
git tag archive/v2.2 origin/v2.2
git push origin archive/v2.2

Bootstrap development from v2.5-beta

git checkout -b development origin/v2.5-beta
git push -u origin development

Delete old remote branches

git push origin --delete v2.5-beta v2.4-beta v2.4-ts v2.3 v2.2

Delete old local branches

git branch -d v2.5-beta

Verify

git branch -a          # should show only main, development
git tag -ln archive/*  # should show archive tags

CI pipeline updates

File Change
.github/workflows/npmpublish-beta.yml Remove — consolidated into single npmpublish.yml
.github/workflows/npmpublish-lts.yml Remove — consolidated into single npmpublish.yml
.github/workflows/npmpublish-main.yml Replace with consolidated npmpublish.yml from qcobjects-cli
.github/workflows/codeql-analysis.yml Branch targets from [v2.3, v2.4] to [main, development]

The consolidated npmpublish.yml should detect the channel from the tag suffix:

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org
      - run: npm ci
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
      - name: Set npm dist-tag
        run: |
          TAG="${GITHUB_REF_NAME#v}"  # strip leading v
          case "$TAG" in
            *-lts)   NPM_TAG=lts ;;
            *-beta)  NPM_TAG=beta ;;
            *)       NPM_TAG=latest ;;
          esac
          npm dist-tag add "$(node -p "require('./package.json').name")@${TAG}" "$NPM_TAG"

Archived tracks

Archive tag Source branch
archive/v2.4-beta origin/v2.4-beta
archive/v2.4-ts origin/v2.4-ts
archive/v2.2 origin/v2.2
v2.3.50 (existing tag) v2.3 branch

Future considerations

  • When starting a new architecture wave (e.g. v2.6), branch from main into a feature branch, develop on development, and release via the same tag flow
  • Archived branches are never deleted from git history — the tags ensure the code is always accessible

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions