@@ -2,7 +2,7 @@ name: Bump Version and Create Release
22
33on :
44 pull_request :
5- types : closed
5+ types : [ closed]
66 branches :
77 - main
88 - development
@@ -17,160 +17,120 @@ jobs:
1717 pull-requests : write
1818
1919 steps :
20+ # 1. สร้าง Token ชั่วคราวจาก GitHub App
21+ - name : Generate GitHub App Token
22+ id : app-token
23+ uses : actions/create-github-app-token@v1
24+ with :
25+ app-id : ${{ secrets.APP_ID }}
26+ private-key : ${{ secrets.APP_PRIVATE_KEY }}
27+
28+ # 2. Checkout โดยใช้ Token ของ App
2029 - name : Checkout Repository
2130 uses : actions/checkout@v4
2231 with :
32+ token : ${{ steps.app-token.outputs.token }} # ใช้ Token ที่เพิ่งสร้าง
2333 fetch-depth : 0
2434
25- - name : Configure Git
35+ # 3. Config Git ให้เป็นตัวตนของ App (Bot Identity)
36+ - name : Configure Git Identity
37+ env :
38+ GH_TOKEN : ${{ steps.app-token.outputs.token }}
2639 run : |
27- git config user.name "github-actions[bot]"
28- git config user.email "github-actions[bot]@users.noreply.github.com"
29-
30- - name : Set up Node.js
31- uses : actions/setup-node@v4
32- with :
33- node-version : ' 22'
34-
35- - name : Get Current Version from GitHub Releases
40+ # ยิง API เพื่อขอข้อมูลของ App Bot ตัวเอง
41+ # GitHub App จะมี user type เป็น "Bot" และมี login name เฉพาะ
42+ USER_INFO=$(curl -s -H "Authorization: token $GH_TOKEN" https://api.github.com/user)
43+
44+ USER_LOGIN=$(echo "$USER_INFO" | jq -r .login)
45+ USER_ID=$(echo "$USER_INFO" | jq -r .id)
46+
47+ # Email ของ GitHub App Bot จะมี format มาตรฐานคือ: id+name[bot]@users.noreply.github.com
48+ USER_EMAIL="${USER_ID}+${USER_LOGIN}@users.noreply.github.com"
49+
50+ echo "Configuring Git as: $USER_LOGIN <$USER_EMAIL>"
51+
52+ git config user.name "$USER_LOGIN"
53+ git config user.email "$USER_EMAIL"
54+
55+ - name : Get Current Version
3656 id : current_version
3757 run : |
38- # Ensure we have tags locally (fetch/prune from origin)
39- git fetch --prune --tags origin
58+ LATEST_TAG=$(git tag -l 'v*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n1)
4059
41- # Prefer latest tag (including pre-releases) matching semver prefix vMAJOR.MINOR.PATCH
42- LATEST_TAG=$(git tag -l 'v*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n1 || true)
43-
44- # if tag latest found
45- if [ -n "$LATEST_TAG" ]; then
46- CURRENT_VERSION="${LATEST_TAG#v}"
47- echo "Found latest tag: $LATEST_TAG"
48- # if tag latest not found
60+ if [ -z "$LATEST_TAG" ]; then
61+ echo "No tags found. Defaulting to v0.0.0"
62+ CURRENT_VERSION="0.0.0"
4963 else
50- # Fallback to GitHub Releases API if no tags are present
51- LATEST_TAG=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
52- https://api.github.com/repos/${{ github.repository }}/releases/latest \
53- | jq -r '.tag_name // empty')
54-
55- # if no releases found
56- if [ -z "$LATEST_TAG" ]; then
57- CURRENT_VERSION="0.1.0"
58- echo "No tags/releases found, using initial version"
59- else
60- CURRENT_VERSION="${LATEST_TAG#v}"
61- echo "Found latest release: $LATEST_TAG"
62- fi
64+ echo "Found latest tag: $LATEST_TAG"
65+ CURRENT_VERSION="${LATEST_TAG#v}"
6366 fi
64-
6567 echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
66- echo "Current version: $CURRENT_VERSION"
6768
6869 - name : Calculate New Version
6970 id : new_version
71+ env :
72+ CURRENT_VERSION : ${{ steps.current_version.outputs.version }}
73+ TARGET_BRANCH : ${{ github.event.pull_request.base.ref }}
74+ SOURCE_BRANCH : ${{ github.event.pull_request.head.ref }}
7075 run : |
71- CURRENT=${{ steps.current_version.outputs.version }}
72- TARGET_BRANCH=${{ github.event.pull_request.base.ref }}
73- SOURCE_BRANCH=${{ github.event.pull_request.head.ref }}
76+ echo "Target: $TARGET_BRANCH | Source: $SOURCE_BRANCH | Current: $CURRENT_VERSION"
77+ BASE_VERSION=${CURRENT_VERSION%%-*}
78+ IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION"
79+ NEW_VERSION=""
7480
75- echo "Target branch: $TARGET_BRANCH"
76- echo "Source branch: $SOURCE_BRANCH"
77-
78- # Split version
79- IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
80- # ex. 0.1.0-dev* or 0.1.0
81-
82- # case hotfix merge to main ex. 0.1.0 -> 0.1.1
81+ # === MAIN ===
8382 if [ "$TARGET_BRANCH" == "main" ]; then
84- echo "On main branch"
85- # split out of text after PATCH -dev* out
86- PATCH=${PATCH%%-*}
87- # ex. 0-dev* -> 0
88- # If source is not a development/, bump patch; otherwise bump minor
89- if [[ "$SOURCE_BRANCH" != "development" ]]; then
90- echo "SOURCE_BRANCH is not development"
91- NEW_MAJOR=$MAJOR
92- NEW_MINOR=$MINOR
93- NEW_PATCH=$((PATCH + 1))
94- NEW_VERSION="$NEW_MAJOR.$NEW_MINOR.$NEW_PATCH"
95- echo "Bumping main: patch bump due to hotfix branch"
96- # if source is development/, bump minor ex. 0.1.0 -> 0.2.0
97- else
98- NEW_MAJOR=$MAJOR
83+ if [ "$SOURCE_BRANCH" == "development" ]; then
9984 NEW_MINOR=$((MINOR + 1))
100- NEW_PATCH=0
101- NEW_VERSION="$NEW_MAJOR.$NEW_MINOR.$NEW_PATCH"
102- echo "Bumping main: minor bump"
85+ NEW_VERSION="$MAJOR.$NEW_MINOR.0"
86+ echo "Strategy: Minor bump (Release)"
87+ else
88+ NEW_PATCH=$((PATCH + 1))
89+ NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
90+ echo "Strategy: Patch bump (Hotfix)"
10391 fi
10492
93+ # === DEVELOPMENT ===
10594 elif [ "$TARGET_BRANCH" == "development" ]; then
106- echo "On development branch"
107- if [[ "$SOURCE_BRANCH" == feat/* ]]; then
108- echo "Bumping development: feature branch"
109- # ถ้า PATCH มี -dev.N อยู่แล้ว ให้เพิ่ม N
110- if [[ "$PATCH" == *"-dev."* ]]; then
111- echo "Feature branch on development with existing dev suffix"
112- DEV_PART=${PATCH#*-dev.}
113- DEV_NUM=${DEV_PART%%-*}
114- DEV_NUM=$((DEV_NUM + 1))
115- # เก็บ prefix ก่อน -dev.N
116- PREFIX=${PATCH%%-dev.*}
117- PATCH="$PREFIX-dev.$DEV_NUM"
118- else
119- echo "Feature branch on development without existing dev suffix"
120- # ถ้าไม่มี -dev.N ให้เริ่มที่ 1
121- PATCH="${PATCH}-dev.1"
122- fi
123-
124- NEW_MAJOR=$MAJOR
125- NEW_MINOR=$MINOR
126- NEW_PATCH=$PATCH
127- NEW_VERSION="$NEW_MAJOR.$NEW_MINOR.$NEW_PATCH"
128- echo "Base version for development branch: $NEW_MAJOR.$NEW_MINOR.$NEW_PATCH"
95+ if [[ "$CURRENT_VERSION" == *"-dev."* ]]; then
96+ LAST_NUM=${CURRENT_VERSION##*.}
97+ NEXT_NUM=$((LAST_NUM + 1))
98+ NEW_VERSION="${BASE_VERSION}-dev.${NEXT_NUM}"
99+ else
100+ NEW_VERSION="${BASE_VERSION}-dev.1"
129101 fi
102+ echo "Strategy: Dev increment"
130103 else
131- echo "Unknown branch: $TARGET_BRANCH"
104+ echo "Error: Unknown target branch ' $TARGET_BRANCH' "
132105 exit 1
133106 fi
134107
108+ echo "New Version Computed: $NEW_VERSION"
135109 echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
136- echo "New version: $NEW_VERSION"
137-
138- - name : Authenticate with GitHub App
139- uses : tibdex/github-app-token@v2.1.0
140- with :
141- app_id : ${{ secrets.APP_ID }}
142- private_key : ${{ secrets.APP_PRIVATE_KEY }}
143110
144- - name : Push Changes and Tags
111+ - name : Push New Tag
145112 run : |
146113 NEW_VERSION=${{ steps.new_version.outputs.version }}
147- git config --global user.name "github-actions"
148- git config --global user.email "github-actions@users.noreply.github.com"
149- git tag "v$NEW_VERSION"
150- git push origin "v$NEW_VERSION"
151- env :
152- GITHUB_TOKEN : ${{ secrets.PAT }}
114+ TAG_NAME="v$NEW_VERSION"
115+
116+ echo "Pushing tag $TAG_NAME"
117+
118+ git tag -a "$TAG_NAME" -m "Release $TAG_NAME"
119+ # Token ถูก set ตั้งแต่ checkout แล้ว จึง push ได้เลย
120+ git push origin "$TAG_NAME"
153121
154122 - name : Create GitHub Release
155123 uses : softprops/action-gh-release@v2
156124 if : github.event.pull_request.base.ref == 'main'
157- env :
158- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
159125 with :
126+ token : ${{ steps.app-token.outputs.token }} # ใช้ App Token สร้าง Release
160127 tag_name : v${{ steps.new_version.outputs.version }}
161- name : Release ${{ steps.new_version.outputs.version }}
128+ name : Release ${{ steps.new_version.outputs.version }}
129+ generate_release_notes : true
162130 body : |
163- # Release ${{ steps.new_version.outputs.version }}
164-
165- ## Version Bump
166- - Previous Version: ${{ steps.current_version.outputs.version }}
167- - New Version: ${{ steps.new_version.outputs.version }}
168- - Target Branch: ${{ github.event.pull_request.base.ref }}
169-
170131 ## Release Details
171- - PR: #${{ github.event.pull_request.number }}
172- - Title: ${{ github.event.pull_request.title }}
173- - Merged by: @${{ github.event.pull_request.merged_by.login }}
174- - Build: [View Workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
175- draft : false
176-
132+ - **Version:** ${{ steps.new_version.outputs.version }}
133+ - **Previous:** ${{ steps.current_version.outputs.version }}
134+ - **PR:** #${{ github.event.pull_request.number }}
135+ - **Branch:** ${{ github.event.pull_request.head.ref }} → ${{ github.event.pull_request.base.ref }}
136+ - **Merged by:** @${{ github.event.pull_request.merged_by.login }}
0 commit comments