88jobs :
99 bump :
1010 runs-on : ubuntu-latest
11-
1211 permissions :
1312 contents : write
1413 packages : write
1514
1615 steps :
17- # 1️⃣ Checkout
1816 - name : Checkout repository
1917 uses : actions/checkout@v4
2018 with :
2119 fetch-depth : 0
2220
23- # 2️⃣ Node.js
2421 - name : Setup Node.js
2522 uses : actions/setup-node@v4
2623 with :
2724 node-version : 23.11.0
2825
29- # 3️⃣ Detect changed projects automatically
26+ # 🔍 Определяем, есть ли флаг [need ci]
27+ - name : Check if [need ci] present
28+ id : need_ci
29+ run : |
30+ if git log ${{ github.event.before }}..${{ github.sha }} --pretty=format:"%s%b" | grep -q "\[need ci\]"; then
31+ echo "force_run=true" >> $GITHUB_OUTPUT
32+ echo "✅ Found [need ci] — forcing full pipeline"
33+ else
34+ echo "force_run=false" >> $GITHUB_OUTPUT
35+ echo "ℹ️ No [need ci] found"
36+ fi
37+
38+ # 🔍 Определяем изменённые проекты
3039 - name : Detect changed projects
3140 id : detect
3241 run : |
33- # Все директории в корне с package.json
3442 PROJECTS=$(find . -maxdepth 1 -type d ! -path . | while read d; do
3543 if [ -f "$d/package.json" ]; then echo "$(basename "$d")"; fi
3644 done)
37-
38- # Только изменённые директории
3945 CHANGED=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | cut -d/ -f1 | sort | uniq)
4046 CHANGED_PROJECTS=$(echo "$PROJECTS" | grep -Fxf <(echo "$CHANGED") || true)
41-
4247 echo "changed_projects=$CHANGED_PROJECTS" >> $GITHUB_OUTPUT
4348 echo "Changed projects: $CHANGED_PROJECTS"
4449
45- # 4️⃣ Determine bump type
50+ # 🧩 Определяем тип версии
4651 - name : Determine bump type
4752 id : bump_type
4853 run : |
@@ -59,27 +64,38 @@ jobs:
5964 echo "bump=$BUMP" >> $GITHUB_OUTPUT
6065 echo "Detected bump type: $BUMP"
6166
62- # 5️⃣ Bump versions, build, Docker
67+ # 🚀 Bump, Build & Docker
6368 - name : Bump, Build & Docker
64- if : steps.bump_type.outputs.bump != 'none' && steps.detect.outputs.changed_projects != ''
69+ if : steps.need_ci.outputs.force_run == 'true' || (steps. bump_type.outputs.bump != 'none' && steps.detect.outputs.changed_projects != '')
6570 id : bump_versions
6671 env :
6772 DOCKERHUB_USER : ${{ secrets.DOCKERHUB_USERNAME }}
6873 DOCKERHUB_TOKEN : ${{ secrets.DOCKERHUB_TOKEN }}
6974 run : |
70- npm install -g conventional-changelog-cli jq commander
75+ npm install -g conventional-changelog-cli jq
7176 echo "${DOCKERHUB_TOKEN}" | docker login -u "${DOCKERHUB_USER}" --password-stdin
7277
7378 BUMP=${{ steps.bump_type.outputs.bump }}
7479 TAGS=""
7580
76- for project in ${{ steps.detect.outputs.changed_projects }}; do
81+ # Если [need ci], прогоняем все проекты
82+ if [ "${{ steps.need_ci.outputs.force_run }}" = "true" ]; then
83+ CHANGED_PROJECTS=$(find . -maxdepth 1 -type d ! -path . | while read d; do
84+ if [ -f "$d/package.json" ]; then echo "$(basename "$d")"; fi
85+ done)
86+ else
87+ CHANGED_PROJECTS=${{ steps.detect.outputs.changed_projects }}
88+ fi
89+
90+ for project in $CHANGED_PROJECTS; do
7791 if [ -f "$project/package.json" ]; then
7892 cd $project
7993 NAME=$(jq -r '.name' package.json)
8094 DESC=$(jq -r '.description // "No description"' package.json)
8195 OLD_VERSION=$(jq -r '.version' package.json)
82- npm version $BUMP --no-git-tag-version
96+ if [ "$BUMP" != "none" ]; then
97+ npm version $BUMP --no-git-tag-version
98+ fi
8399 NEW_VERSION=$(jq -r '.version' package.json)
84100
85101 conventional-changelog -p angular -i CHANGELOG.md -s -r 1 || echo "No changelog generated"
@@ -125,72 +141,74 @@ jobs:
125141 done
126142 echo "tags=$TAGS" >> $GITHUB_OUTPUT
127143
128- # 6️⃣ Commit & push
144+ # 💾 Commit and push changes
129145 - name : Commit and push changes
130- if : steps.bump_type.outputs.bump != 'none' && steps.detect.outputs.changed_projects != ''
146+ if : steps.need_ci.outputs.force_run == 'true' || (steps. bump_type.outputs.bump != 'none' && steps.detect.outputs.changed_projects != '')
131147 run : |
132148 git config user.name "github-actions[bot]"
133149 git config user.email "github-actions[bot]@users.noreply.github.com"
134- git add */package.json */CHANGELOG.md
135- git commit -m "chore: auto bump ${{ steps.bump_type.outputs.bump }} version [skip ci]" || echo "No changes to commit "
150+ git add */package.json */CHANGELOG.md || true
151+ git commit -m "chore: auto bump version [skip ci]" || echo "No changes"
136152 git push origin main
137153 git push origin --tags
138154
139- # 7️⃣ Upload artifacts
155+ # 📦 Upload artifacts
140156 - name : Upload artifacts
141- if : steps.bump_versions.outputs.tags != ''
157+ if : steps.need_ci.outputs.force_run == 'true' || steps. bump_versions.outputs.tags != ''
142158 uses : actions/upload-artifact@v4
143159 with :
144160 name : project-builds
145- path : |
146- **/artifacts/**
161+ path : " **/artifacts/**"
147162 if-no-files-found : ignore
148163
149- # 8️⃣ Create release & Telegram notification
164+ # 🏷️ Create release & Telegram
150165 - name : Create releases & send Telegram message
151- if : steps.bump_versions.outputs.tags != ''
166+ if : steps.need_ci.outputs.force_run == 'true' || steps. bump_versions.outputs.tags != ''
152167 env :
153168 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
154169 DOCKERHUB_USER : ${{ secrets.DOCKERHUB_USERNAME }}
155170 TELEGRAM_BOT_TOKEN : ${{ secrets.TELEGRAM_BOT_TOKEN }}
156171 TELEGRAM_CHAT_ID : ${{ secrets.TELEGRAM_CHAT_ID }}
157172 run : |
158- # 🔒 skip Telegram if commit has [hidden]
159173 if git log ${{ github.event.before }}..${{ github.sha }} --pretty=format:"%s%b" | grep -q "\[hidden\]"; then
160- echo "🔒 '[hidden]' found in commits — skipping Telegram notification "
174+ echo "🔒 '[hidden]' found — skipping Telegram"
161175 SKIP_TELEGRAM=1
162176 else
163177 SKIP_TELEGRAM=0
164178 fi
165179
166- for TAG in ${{ steps.bump_versions.outputs.tags }}; do
180+ TAGS="${{ steps.bump_versions.outputs.tags }}"
181+ if [ -z "$TAGS" ] && [ "${{ steps.need_ci.outputs.force_run }}" = "true" ]; then
182+ TAGS=$(find . -maxdepth 1 -type d ! -path . -exec bash -c 'cd {} && if [ -f package.json ]; then NAME=$(jq -r .name package.json); VER=$(jq -r .version package.json); echo "$(basename "$PWD")@$VER"; fi' \;)
183+ fi
184+
185+ for TAG in $TAGS; do
167186 PROJECT=$(echo "$TAG" | cut -d@ -f1)
168- CHANGELOG_PATH="$PROJECT/CHANGELOG.md"
169- ARTIFACTS_PATH="$PROJECT/artifacts"
170187 PKG="$PROJECT/package.json"
188+ [ ! -f "$PKG" ] && continue
171189
172190 NAME=$(jq -r '.name' "$PKG")
173191 DESC=$(jq -r '.description // "No description"' "$PKG")
174192 VERSION=$(jq -r '.version' "$PKG")
193+ CHANGELOG_PATH="$PROJECT/CHANGELOG.md"
194+ ARTIFACTS_PATH="$PROJECT/artifacts"
195+
175196 RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/${TAG}"
176197 PROJECT_URL="https://github.com/${{ github.repository }}/tree/main/${PROJECT}"
177198
178199 NOTES="📢 *${NAME} v${VERSION} released!*\n\n_${DESC}_\n\n"
179-
180200 if [ -f "$CHANGELOG_PATH" ]; then
181201 BODY=$(awk '/^##/{i++}i==1' "$CHANGELOG_PATH" | head -n 20)
182202 NOTES+="*Changelog:*\n\`\`\`\n$BODY\n\`\`\`\n"
183203 fi
184204
185- # Create GitHub release
186205 if [ -d "$ARTIFACTS_PATH" ]; then
187206 FILES=$(find "$ARTIFACTS_PATH" -type f)
188207 gh release create "$TAG" --title "$TAG" --notes "$NOTES" $FILES || echo "Release exists"
189208 else
190209 gh release create "$TAG" --title "$TAG" --notes "$NOTES" || echo "Release exists"
191210 fi
192211
193- # Telegram
194212 if [ "$SKIP_TELEGRAM" -eq 0 ]; then
195213 BUTTONS="["
196214 if [ -d "$ARTIFACTS_PATH" ]; then
@@ -206,7 +224,7 @@ jobs:
206224 BUTTONS="${BUTTONS}[{\"text\":\"🧱 Project folder\",\"url\":\"${PROJECT_URL}\"}],"
207225 BUTTONS="${BUTTONS}[{\"text\":\"🔗 View release\",\"url\":\"${RELEASE_URL}\"}]"
208226 BUTTONS="${BUTTONS}]"
209- BUTTONS=$(echo "$BUTTONS" | sed 's/,]/]/') # cleanup trailing commas
227+ BUTTONS=$(echo "$BUTTONS" | sed 's/,]/]/')
210228
211229 curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
212230 -H "Content-Type: application/json" \
0 commit comments