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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions