|
1 | | -# version-management |
2 | | - |
3 | | -> **Centralized, reusable GitHub Actions workflow for automated versioning (Spring Boot & Next.js)** |
4 | | -> On pushes to the default branch (`main`) with a compliant commit message, this project performs **Version bump → Project file sync → CHANGELOG update → Git Tag creation/push** in a standardized way. |
5 | | -> It also emits a `repository_dispatch` event **only when a version bump actually happens**, so you can trigger follow‑up workflows (e.g., `apk-build.yml`) conditionally. |
6 | | -
|
7 | | -> **한국어 문서** → [README.md](README.md) |
8 | | -
|
9 | | ---- |
10 | | - |
11 | | -## 🚀 Features |
12 | | - |
13 | | -- **Two frameworks supported** |
14 | | - - **Spring Boot (Gradle/Groovy)**: updates `version` in `build.gradle`, optionally replaces the `version:` key in `src/main/resources/application.yml` |
15 | | - - **Next.js (TypeScript)**: updates `package.json.version` and creates/updates `src/constants/version.ts` (path is configurable) |
16 | | -- **Commit‑driven versioning** |
17 | | - - `version(major): ...` |
18 | | - - `version(minor): ...` |
19 | | - - `version(patch): ...` |
20 | | -- **Policy guarantees** |
21 | | - - Bump **only on the default branch (`main`)** |
22 | | - - Detect current version in order: **Tag → Files → Default value** |
23 | | - - `CHANGELOG.md` is **prepended at the top** (insert banner only once; subsequent entries accumulate **under** the banner) |
24 | | - - Create & push **Git Tag** (`vX.Y.Z`) + push **release commit** |
25 | | - Release commit message: `chore(release): vX.Y.Z {original subject description} [skip version]` |
26 | | - - **No bump → workflow still succeeds** (handy for pipeline branching) |
27 | | -- **Follow‑up workflow integration** |
28 | | - - Sends `repository_dispatch` only when the version actually bumped (default event: `version-bumped`) |
29 | | - - Payload: `new_version`, `new_tag`, `bump_level`, `sha` |
30 | | - |
31 | | ---- |
32 | | - |
33 | | -## 📦 Repository layout |
34 | | - |
35 | | -``` |
36 | | -version-management/ |
37 | | -├─ action.yml # Composite action entry (can be used directly) |
38 | | -├─ scripts/ |
39 | | -│ ├─ compute-bump.mjs # Commit inspection + version calculation |
40 | | -│ ├─ sync-files.mjs # File sync + commit |
41 | | -│ ├─ update-changelog.mjs # CHANGELOG prepend (+ initial banner) |
42 | | -│ └─ create-tag.mjs # Tag create/push + release commit handling |
43 | | -└─ .github/ |
44 | | - └─ workflows/ |
45 | | - └─ auto-version.yml # Reusable workflow (workflow_call) orchestrator |
46 | | -``` |
47 | | -> **Why split it like this?** |
48 | | -> The **reusable workflow** handles pipeline orchestration (permissions, concurrency, dispatch), while the **composite action** bundles the actual logic (bump/file updates/changelog/tagging) so it can be reused anywhere. |
49 | | -
|
50 | | ---- |
51 | | - |
52 | | -## 🧭 Quick start (consumer repo) |
53 | | - |
54 | | -### 1) Use the **reusable workflow** (recommended) |
55 | | - |
56 | | -**Consumer repo**: `.github/workflows/version-management.yml` |
57 | | - |
| 1 | +# Release Notes — v1.0.0 |
| 2 | + |
| 3 | +**Tag:** `v1.0.0` |
| 4 | +**Summary:** Official **1.0** release of a centralized, reusable version‑management workflow for **Spring Boot · Next.js · Plain** projects. It performs commit‑driven SemVer bumps, project file synchronization, top‑prepended CHANGELOG updates, and Git tag creation/push in a consistent way. It also emits `repository_dispatch` **only when a bump occurs**, enabling conditional follow‑up pipelines. |
| 5 | + |
| 6 | +## ✨ Highlights |
| 7 | +- **SemVer bump from commit subject**: `version(major|min|patch): {message}` |
| 8 | +- **Project file synchronization** |
| 9 | + - **Spring Boot**: update `version` in `build.gradle`; optionally update `version:` in `src/main/resources/application.yml` |
| 10 | + - **Next.js**: update `package.json.version`; create/replace `src/constants/version.ts` (configurable path); update `package-lock.json` |
| 11 | + - **Plain**: create/replace a **version file (`VERSION`)** so the file contains **only one line** with the new version |
| 12 | + - If missing → create file with `X.Y.Z` |
| 13 | + - If present → **overwrite entire content** with `X.Y.Z` |
| 14 | +- **Automatic CHANGELOG** |
| 15 | + - Prepend new section to the top |
| 16 | + - Insert a banner once; subsequent entries accumulate under the banner |
| 17 | +- **Git tagging** |
| 18 | + - Format: `vX.Y.Z` |
| 19 | + - Release commit message: `chore(release): vX.Y.Z {message} [skip version]` |
| 20 | +- **Follow‑up workflows** |
| 21 | + - Send `repository_dispatch` (default: `version-bumped`) **only when bumped** |
| 22 | + |
| 23 | +## 🔧 Usage examples |
| 24 | + |
| 25 | +### Reusable workflow (recommended) |
58 | 26 | ```yaml |
59 | | -name: Version Management (from chuseok22/version-management) |
60 | | - |
61 | | -on: |
62 | | - push: |
63 | | - branches: [ main ] |
64 | | - workflow_dispatch: |
65 | | - |
66 | | -permissions: |
67 | | - contents: write |
68 | | - actions: read |
69 | | - |
70 | 27 | jobs: |
71 | 28 | chuseok22-version-bump: |
72 | 29 | uses: chuseok22/version-management/.github/workflows/auto-version.yml@v1 |
73 | 30 | with: |
74 | | - project_type: "auto" # spring | next | auto |
75 | | - default_branch: "main" |
76 | | - tag_prefix: "v" |
77 | | - default_version: "0.0.0" |
78 | | - next_constants_path: "src/constants/version.ts" # for Next.js only |
79 | | - sync_app_yaml: "false" # Spring application.yml version update |
80 | | - workdir: "" # subdir in a monorepo, e.g., "backend"/"web" |
81 | | - dispatch_on_bump: "true" # trigger follow-ups only when bumped |
82 | | - dispatch_event_type: "version-bumped" |
| 31 | + project_type: auto # spring | next | plain | auto |
| 32 | + default_branch: main |
| 33 | + tag_prefix: v |
| 34 | + default_version: 0.0.0 |
| 35 | + next_constants_path: src/constants/version.ts # Next.js only |
| 36 | + sync_app_yaml: false |
| 37 | + workdir: "" |
| 38 | + dispatch_on_bump: true |
| 39 | + dispatch_event_type: version-bumped |
| 40 | + plain_version_file: VERSION |
83 | 41 | ``` |
84 | 42 |
|
85 | | -### 2) (Advanced) Use only the logic in an existing CI |
86 | | -
|
87 | | -Call the **composite action** directly inside your job: |
88 | | -
|
| 43 | +### Composite action (logic only) |
89 | 44 | ```yaml |
90 | | -jobs: |
91 | | - some-job: |
92 | | - runs-on: ubuntu-latest |
93 | | - steps: |
94 | | - - uses: actions/checkout@v4 |
95 | | - with: { fetch-depth: 0 } |
96 | | - - uses: actions/setup-node@v4 |
97 | | - with: { node-version: 20 } |
98 | | - |
99 | | - - name: Version bump only |
100 | | - uses: chuseok22/version-management@v1 |
101 | | - with: |
102 | | - project_type: auto |
103 | | - default_branch: main |
104 | | - tag_prefix: v |
105 | | - default_version: 0.0.0 |
106 | | - next_constants_path: src/constants/version.ts |
107 | | - sync_app_yaml: "false" |
108 | | - workdir: "" |
| 45 | +- uses: actions/checkout@v4 |
| 46 | + with: { fetch-depth: 0 } |
| 47 | +- uses: actions/setup-node@v4 |
| 48 | + with: { node-version: 20 } |
| 49 | +- uses: chuseok22/version-management@v1 |
| 50 | + with: |
| 51 | + project_type: auto |
| 52 | + default_branch: main |
| 53 | + tag_prefix: v |
| 54 | + default_version: 0.0.0 |
| 55 | + next_constants_path: src/constants/version.ts |
| 56 | + sync_app_yaml: false |
| 57 | + workdir: "" |
| 58 | + plain_version_file: VERSION |
109 | 59 | ``` |
110 | 60 |
|
111 | | ---- |
| 61 | +## 🐛 Fixes & improvements |
| 62 | +- **Plain project support**: auto create/replace `VERSION` (keep only the new version line); new input `plain_version_file` |
| 63 | +- **Tag matching improved**: robust for **multi‑digit** segments like `v1.0.14` |
| 64 | +- **Auto detection**: `package.json` → **next**, `build.gradle` → **spring**, otherwise → **plain** |
| 65 | +- **Release commit normalization**: includes original subject description + always appends `[skip version]` |
| 66 | +- **CHANGELOG banner/header ordering**: banner pinned to the very top |
112 | 67 |
|
113 | | -## ✍️ Commit convention (required) |
114 | | -
|
115 | | -Version is determined **by the commit subject**: |
116 | | -
|
117 | | -- `version(major): message` → increase **MAJOR** (+1), reset MINOR/PATCH to 0 |
118 | | -- `version(minor): message` → increase **MINOR** (+1), reset PATCH to 0 |
119 | | -- `version(patch): message` → increase **PATCH** (+1) |
120 | | -- Any other commit → **no bump** (workflow still succeeds) |
121 | | - |
122 | | -Examples: |
123 | | -``` |
124 | | -version(major): drop legacy API |
125 | | -version(minor): add CSV export |
126 | | -version(patch): fix null check |
127 | | -``` |
128 | | - |
129 | | ---- |
130 | | - |
131 | | -## ⚙️ Inputs (overview) |
132 | | - |
133 | | -**Reusable workflow** `.github/workflows/auto-version.yml` (`on: workflow_call`) |
134 | | - |
135 | | -| Input | Default | Description | |
136 | | -|---|---|---| |
137 | | -| `project_type` | `auto` | `spring` \| `next` \| `auto` (auto-detect: `package.json` → next, `build.gradle` → spring) | |
138 | | -| `default_branch` | `main` | Only bump on this branch | |
139 | | -| `tag_prefix` | `v` | Tag prefix (e.g., `v1.2.3`) | |
140 | | -| `default_version` | `0.0.0` | Seed version when no tag/file exists | |
141 | | -| `next_constants_path` | `src/constants/version.ts` | Next.js constant file path | |
142 | | -| `sync_app_yaml` | `false` | Update `version:` in Spring `src/main/resources/application.yml` if present | |
143 | | -| `workdir` | `""` | Subdirectory in a monorepo (e.g., `backend`, `web`) | |
144 | | -| `dispatch_on_bump` | `true` | Send `repository_dispatch` only when a bump occurred | |
145 | | -| `dispatch_event_type` | `version-bumped` | Event type for follow-up workflows | |
146 | | - |
147 | | -> The **composite action** (`action.yml`) accepts the same/similar inputs. |
148 | | - |
149 | | ---- |
150 | | - |
151 | | -## 🧩 CHANGELOG policy |
152 | | - |
153 | | -- On each release, **prepend** a new version section to the very top. |
154 | | -- On first creation, insert the **banner once** (future entries are added **below** the banner). |
155 | | -- The release commit message **always includes `[skip version]`** to prevent re-run loops. |
156 | | - |
157 | | -Banner example: |
158 | | -``` |
159 | | -<!-- vm-banner:start --> |
160 | | -🔧 **Version Management Auto Change History** |
161 | | -
|
162 | | -This file is automatically generated and maintained by the centralized workflow (**Version Management**). |
163 | | -Author: **Chuseok22** · https://github.com/Chuseok22 |
164 | | -Workflow repo: https://github.com/Chuseok22/version-management |
165 | | -
|
166 | | -※ Manual edits may be overwritten in future releases. |
167 | | -<!-- vm-banner:end --> |
168 | | -``` |
169 | | - |
170 | | ---- |
171 | | - |
172 | | -## 🔒 Requirements & permissions |
| 68 | +## ⚠️ Notes / limitations |
| 69 | +- Bump happens **only** on `default_branch` (default: `main`). |
| 70 | + Commits with `version(...)` on other branches are **skipped** (workflow succeeds). |
| 71 | +- When using the **composite action alone**, no `repository_dispatch` is sent. |
| 72 | + Use the **reusable workflow** if you need dispatch. |
173 | 73 |
|
| 74 | +## ✅ Requirements |
174 | 75 | - Runner: `ubuntu-latest`, Node: `20` |
175 | | -- Permissions: `contents: write` |
176 | | -- Checkout: `actions/checkout@v4` with `fetch-depth: 0` (tags/history required) |
177 | | - |
178 | | ---- |
179 | | - |
180 | | -**Author: [Chuseok22](https://github.com/Chuseok22)** · Repo: https://github.com/Chuseok22/version-management |
| 76 | +- Permission: `contents: write` |
| 77 | +- Checkout: `actions/checkout@v4` with `fetch-depth: 0` |
0 commit comments