Skip to content

프론트엔드 릴리즈 워크플로우 및 Vercel 배포 자동화#516

Open
Goder-0 wants to merge 1 commit into
mainfrom
feature/#514-vercel-release-workflow
Open

프론트엔드 릴리즈 워크플로우 및 Vercel 배포 자동화#516
Goder-0 wants to merge 1 commit into
mainfrom
feature/#514-vercel-release-workflow

Conversation

@Goder-0
Copy link
Copy Markdown
Contributor

@Goder-0 Goder-0 commented Jun 1, 2026

관련 이슈

PR 설명

  • 기존 ci.yml은 유지하고, PR / main 기준 Vercel Preview 배포를 담당하는 cd.yml을 추가했습니다.
  • 태그(v*) 기준으로만 Vercel Production 배포와 GitHub Release 생성을 수행하는 release.yml을 추가했습니다.
  • Preview 배포 URL을 PR 코멘트로 남기도록 구성했습니다.

비고

  • 역할을 CI / CD / release로 분리했습니다.
  • Production 배포는 태그 기반 릴리즈에서만 수행되도록 구성했습니다.

- Add a preview deployment workflow for pull requests and main updates.
- Add a tag-based production release workflow.
- Generate GitHub Releases from the production workflow.
- Closes #514.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Walkthrough

이 PR은 프론트엔드 배포 자동화를 위한 두 개의 GitHub Actions 워크플로를 추가합니다. cd.yml은 main 브랜치 푸시 및 PR 이벤트에서 Vercel 프리뷰 배포를 수행하고 PR 코멘트로 배포 URL을 공유합니다. release.yml은 버전 태그 푸시에서 Vercel 프로덕션 배포를 실행한 후 GitHub 릴리스를 자동으로 생성합니다. 두 워크플로 모두 pnpm 및 Node.js를 설정하고 Vercel CLI로 환경별 빌드 및 배포를 수행합니다.

Possibly related issues

  • #514: PR/main 프리뷰 배포, 태그 릴리즈 프로덕션 배포, GitHub 릴리스 자동 생성 목표를 구현합니다.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 두 개의 새로운 워크플로우(cd.yml과 release.yml) 추가 및 Vercel 자동화라는 주요 변경사항을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿을 따르며 관련 이슈, 추가된 워크플로우의 역할 분리, 예상 동작을 구체적으로 설명하고 있습니다.
Linked Issues check ✅ Passed 코드 변경사항이 이슈 #514의 모든 주요 목표를 충족합니다: Preview/Production 배포 역할 분리, PR 코멘트 기반 URL 노출, 태그 기반 릴리즈 자동화, GitHub Release 자동 생성.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #514의 범위 내에 있으며, 두 개의 새로운 워크플로우 파일 추가 외에 기타 수정사항이 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#514-vercel-release-workflow

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
.github/workflows/cd.yml (1)

33-34: ⚡ Quick win

체크아웃 자격증명 영속화 비활성화 권장.

이후 단계에서 git push를 하지 않으므로 actions/checkout가 워크플로 전체에 토큰을 영속화할 필요가 없습니다. persist-credentials: false로 노출 표면을 줄이는 것을 권장합니다. 더불어 actions/checkout@v4, pnpm/action-setup@v4, actions/setup-node@v4, actions/github-script@v7 등 외부 액션을 커밋 SHA로 고정하면 공급망 공격 표면을 추가로 줄일 수 있습니다.

🔒 persist-credentials 비활성화
       - name: Checkout repository
         uses: actions/checkout@v4
+        with:
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/cd.yml around lines 33 - 34, Update the Checkout step
(named "Checkout repository") to set persist-credentials: false so the workflow
does not persist the GITHUB_TOKEN unnecessarily; also pin third‑party actions
used in the workflow (actions/checkout, pnpm/action-setup, actions/setup-node,
actions/github-script) to specific commit SHAs instead of loose tags (e.g.,
replace `@v4/`@v7 with the corresponding commit SHA) to reduce supply‑chain risk
and exposure.
.github/workflows/release.yml (1)

24-25: ⚡ Quick win

체크아웃 자격증명 영속화 비활성화 권장.

릴리스 단계는 GITHUB_TOKEN/시크릿으로 동작하며 git push가 없으므로 persist-credentials: false를 설정하는 것을 권장합니다. 또한 actions/checkout@v4, pnpm/action-setup@v4, actions/setup-node@v4, softprops/action-gh-release@v2를 커밋 SHA로 고정하면 공급망 보안을 강화할 수 있습니다.

🔒 persist-credentials 비활성화
       - name: Checkout repository
         uses: actions/checkout@v4
+        with:
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 24 - 25, The checkout step
currently uses actions/checkout@v4 without disabling credential persistence;
update the Checkout repository step (actions/checkout@v4) to include
persist-credentials: false to avoid persisting GITHUB_TOKEN credentials during
the release workflow, and also pin third-party actions used in the workflow
(pnpm/action-setup@v4, actions/setup-node@v4, softprops/action-gh-release@v2) to
specific commit SHAs instead of floating tags to improve supply-chain security;
ensure the changes are applied in the release workflow file where the Checkout
repository step and those action usages are defined.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/cd.yml:
- Around line 53-64: The Vercel steps ("Pull Vercel preview environment", "Build
Vercel artifacts", and "Deploy preview to Vercel") assume secrets and PR write
permissions and will fail for forked PRs; update the workflow so these steps run
only for non-forked PRs by adding a conditional (e.g., check head.repo.fork ==
false) to each step or move only the secret/permission-requiring parts into a
separate pull_request_target job, keeping the deploy/comment logic guarded from
untrusted fork runs and referencing the step names above to locate where to add
the condition or extraction.

In @.github/workflows/release.yml:
- Around line 53-61: The step is vulnerable because echo "- Tag: ${{
github.ref_name }}" expands the GitHub expression directly into the shell
(possible code injection); instead pass the tag through the environment and
reference that env var in the run block. Update the job to set an env variable
(e.g., TAG) to ${{ github.ref_name }} and then in the run section write the
summary using that env var (e.g., echo "- Tag: $TAG" >> "$GITHUB_STEP_SUMMARY"),
keeping deployment_url handling unchanged.

---

Nitpick comments:
In @.github/workflows/cd.yml:
- Around line 33-34: Update the Checkout step (named "Checkout repository") to
set persist-credentials: false so the workflow does not persist the GITHUB_TOKEN
unnecessarily; also pin third‑party actions used in the workflow
(actions/checkout, pnpm/action-setup, actions/setup-node, actions/github-script)
to specific commit SHAs instead of loose tags (e.g., replace `@v4/`@v7 with the
corresponding commit SHA) to reduce supply‑chain risk and exposure.

In @.github/workflows/release.yml:
- Around line 24-25: The checkout step currently uses actions/checkout@v4
without disabling credential persistence; update the Checkout repository step
(actions/checkout@v4) to include persist-credentials: false to avoid persisting
GITHUB_TOKEN credentials during the release workflow, and also pin third-party
actions used in the workflow (pnpm/action-setup@v4, actions/setup-node@v4,
softprops/action-gh-release@v2) to specific commit SHAs instead of floating tags
to improve supply-chain security; ensure the changes are applied in the release
workflow file where the Checkout repository step and those action usages are
defined.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: bce9260c-e265-4a50-aa5e-04e038825c87

📥 Commits

Reviewing files that changed from the base of the PR and between 5b92945 and b780595.

📒 Files selected for processing (2)
  • .github/workflows/cd.yml
  • .github/workflows/release.yml

Comment thread .github/workflows/cd.yml
Comment on lines +53 to +64
- name: Pull Vercel preview environment
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Vercel artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy preview to Vercel
id: deploy
shell: bash
run: |
deployment_url="$(vercel deploy --prebuilt --archive=tgz --token=${{ secrets.VERCEL_TOKEN }})"
echo "deployment_url=${deployment_url}" >> "$GITHUB_OUTPUT"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 포크 PR 허용 여부 및 다른 워크플로의 트리거 패턴 확인
fd -e yml -e yaml . .github/workflows --exec rg -n 'pull_request|fork|secrets\.' {} \;

Repository: Team-SoFa/linkiving

Length of output: 1346


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/cd.yml"
if [ ! -f "$FILE" ]; then
  echo "Missing $FILE" >&2
  exit 1
fi

echo "=== on: section (first 120 lines) ==="
nl -ba "$FILE" | sed -n '1,120p'

echo "=== workflow/jobs/steps around Vercel deploy (40-120 lines) ==="
nl -ba "$FILE" | sed -n '35,120p'

Repository: Team-SoFa/linkiving

Length of output: 163


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/cd.yml"
wc -l "$FILE"

echo "=== cd.yml: 1-120 ==="
sed -n '1,120p' "$FILE"

echo "=== cd.yml: 120-end ==="
sed -n '121,$p' "$FILE"

Repository: Team-SoFa/linkiving

Length of output: 2996


🌐 Web query:

GitHub Actions pull_request events from fork secrets.VERCEL_TOKEN not available GITHUB_TOKEN read-only even if permissions specified pull-requests: write

💡 Result:

In GitHub Actions, when a workflow is triggered by the pull_request event for a pull request coming from a fork, secrets (including your secrets.VERCEL_TOKEN) are not passed to the workflow, and GitHub also applies a security model that can make the GITHUB_TOKEN effectively read-only for that run even if you set permissions in the workflow YAML. 1) Why secrets.VERCEL_TOKEN is “not available” - GitHub documents that secrets are not passed to workflows that are triggered by a pull request from a fork. This means ${{ secrets.VERCEL_TOKEN }} will be unset/empty in that fork PR run (by design/security restriction). [1] 2) Why GITHUB_TOKEN becomes read-only and ignores “pull-requests: write” - GitHub applies a read-only permissions adjustment for pull-request runs triggered from forked repositories (the docs clarification indicates write permissions are changed to read-only except for pull_request_target). [2][3] - Therefore, on pull_request from forks, you should not expect permissions: pull-requests: write to grant write access in the way it does for same-repo pull requests. [3] 3) The supported workaround (use pull_request_target with caution) - If you need a workflow to run with access to secrets (and generally with broader token permissions) for PRs originating from forks, GitHub’s guidance is to use the pull_request_target event so the workflow runs in the context of the base repository and can access secrets/tokens. [4] - Note: pull_request_target runs against the base context rather than the PR head context; GitHub explicitly warns to avoid running unsafe code from the pull request because that could alter the repository or steal secrets. [5][4] 4) Practical guidance for your case (Vercel deploy on fork PRs) - For fork-origin PRs on pull_request, plan for VERCEL_TOKEN to be unavailable and therefore disable/skip any steps that require it. - If you truly must deploy preview from fork PRs, switch to pull_request_target and only check out the PR code after you have appropriate review/guardrails (the security risk is real, which is why many actions default to not deploying fork PRs). [6][5] If you paste your workflow YAML (especially the on: trigger, permissions:, and where you use secrets.VERCEL_TOKEN), I can suggest an exact conditional structure to prevent the token from being required on fork PRs while still allowing the behavior you want on internal PRs.

Citations:


🌐 Web query:

GitHub Actions pull_request events from fork secrets not passed GITHUB_TOKEN read-only even if permissions pull-requests: write

💡 Result:

For pull requests from forks using the pull_request event, GitHub intentionally prevents your workflow from getting write-capable GITHUB_TOKEN or any repository secrets beyond the default token’s limited access: repository secrets are not passed to workflows triggered by a pull request from a fork, and any “write” token permissions are adjusted down to read-only unless you use pull_request_target [1][2][3]. As a result, setting pull-requests: write (or broader write scopes) won’t be honored for the forked-PR workflow context; GitHub changes those permissions to read-only for security [1][4][3]. What you can do instead 1) If you need secrets and write access for forked PRs, the supported mechanism is pull_request_target (it runs in the base repository context and can access secrets; by default it grants read/write token permissions unless you restrict them) [5][3]. But you must not check out or execute untrusted code from the fork in that workflow; only do trusted actions like labeling/commenting/triage [5]. 2) Keep pull_request for untrusted code execution and move any secret-dependent or write-permission steps behind a trusted workflow (commonly by splitting workflows, or using pull_request_target only for metadata/reporting) [5]. 3) Use least-privilege permissions anyway: the GITHUB_TOKEN’s granted scopes are controlled via the permissions key, but for forked pull_request triggers GitHub still applies the fork-related read-only/secret-withholding restrictions [6][1][3]. Bottom line answer to your query - Yes: for fork PRs triggered with pull_request, GitHub will withhold secrets and downgrade any requested token write permissions (including pull-requests: write) to read-only for that workflow run [1][3]. - There is no way to “force” pull_request fork runs to get pull-requests: write with repository secrets; the security restriction is intentional [1][3]. - The practical option is to use pull_request_target for the privileged portion, with the critical rule that you do not execute fork code in that context [5].

Citations:


포크 PR에서 Vercel 토큰/PR 코멘트 권한이 막혀 워크플로가 실패할 수 있어요.

  • 현재 .github/workflows/cd.ymlpull_request 트리거에서는 secrets.VERCEL_TOKEN을 전제로 vercel pull/build/deploy를 항상 실행하는데, 포크 PR의 pull_request에서는 시크릿이 전달되지 않아 이 단계가 실패할 수 있습니다.
  • 또한 permissions: pull-requests: write를 설정해도 포크 PR pull_request 실행에서는 GITHUB_TOKEN이 write로 동작하지 않을 수 있어 코멘트 작성 단계(createComment/updateComment)도 실패할 수 있습니다.
  • 대응: 포크 PR이면 해당 단계들을 if: ...head.repo.fork == false로 스킵하거나, 권한/시크릿이 필요한 부분만 pull_request_target로 분리(비신뢰 코드 실행 주의)하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/cd.yml around lines 53 - 64, The Vercel steps ("Pull
Vercel preview environment", "Build Vercel artifacts", and "Deploy preview to
Vercel") assume secrets and PR write permissions and will fail for forked PRs;
update the workflow so these steps run only for non-forked PRs by adding a
conditional (e.g., check head.repo.fork == false) to each step or move only the
secret/permission-requiring parts into a separate pull_request_target job,
keeping the deploy/comment logic guarded from untrusted fork runs and
referencing the step names above to locate where to add the condition or
extraction.

Comment on lines +53 to +61
run: |
deployment_url="$(vercel deploy --prebuilt --archive=tgz --prod --token=${{ secrets.VERCEL_TOKEN }})"
echo "deployment_url=${deployment_url}" >> "$GITHUB_OUTPUT"
{
echo "Production release deployed."
echo
echo "- Tag: ${{ github.ref_name }}"
echo "- URL: ${deployment_url}"
} >> "$GITHUB_STEP_SUMMARY"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

스텝 요약에서 github.ref_name을 직접 셸로 확장하지 마세요 (코드 인젝션).

echo "- Tag: ${{ github.ref_name }}"는 표현식을 셸 스크립트로 직접 전개합니다. git 태그 이름에는 $, (, ), 백틱 등 셸 메타문자가 포함될 수 있어, 태그를 푸시할 수 있는 권한자가 임의 명령을 실행할 수 있는 인젝션 경로가 됩니다(이 잡은 VERCEL_TOKEN 시크릿에 접근). env로 전달해 안전하게 참조하세요.

🛡️ env 변수로 전달
       - name: Deploy production to Vercel
         id: deploy
         shell: bash
+        env:
+          REF_NAME: ${{ github.ref_name }}
         run: |
           deployment_url="$(vercel deploy --prebuilt --archive=tgz --prod --token=${{ secrets.VERCEL_TOKEN }})"
           echo "deployment_url=${deployment_url}" >> "$GITHUB_OUTPUT"
           {
             echo "Production release deployed."
             echo
-            echo "- Tag: ${{ github.ref_name }}"
+            echo "- Tag: ${REF_NAME}"
             echo "- URL: ${deployment_url}"
           } >> "$GITHUB_STEP_SUMMARY"
🧰 Tools
🪛 zizmor (1.25.2)

[error] 59-59: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 53 - 61, The step is vulnerable
because echo "- Tag: ${{ github.ref_name }}" expands the GitHub expression
directly into the shell (possible code injection); instead pass the tag through
the environment and reference that env var in the run block. Update the job to
set an env variable (e.g., TAG) to ${{ github.ref_name }} and then in the run
section write the summary using that env var (e.g., echo "- Tag: $TAG" >>
"$GITHUB_STEP_SUMMARY"), keeping deployment_url handling unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

프론트엔드 릴리즈 워크플로우 및 Vercel 배포 자동화

1 participant