Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
script: |
// release-please가 자동 생성하는 Release PR은 이슈가 없으므로 예외
const headRef = context.payload.pull_request.head.ref || '';
if (headRef.startsWith('release-please--')) {
core.info('release-please Release PR — 이슈 참조 검사 생략');
return;
}
const body = context.payload.pull_request.body || '';
// "#123", "Closes #123", "Fixes #45", "Resolves: #6" 등 + 전체 URL 형태 모두 허용
const ref = /(close[sd]?|fix(e[sd])?|resolve[sd]?)?\s*:?\s*#\d+/i.test(body)
Expand Down
97 changes: 97 additions & 0 deletions .github/workflows/release-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Release Beta

# 베타는 별도 브랜치 없이 main에서 수동으로 발행한다 (prerelease 태그).
# 검증된 빌드는 이후 일반 머지 흐름(release-please)으로 스테이블 승급.
on:
workflow_dispatch:

permissions:
contents: read

jobs:
beta:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 리포지토리 체크아웃
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false

- name: Node.js 설정
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: npm

- name: 베타 버전 계산
id: ver
run: |
BASE=$(node -p "require('./package.json').version" | sed 's/-.*//')
echo "tag=v${BASE}-beta.${GITHUB_RUN_NUMBER}" >> "$GITHUB_OUTPUT"

- name: 의존성 설치
run: npm ci

- name: 프로덕션 빌드 (베타)
run: npm run build
env:
RELEASE_CHANNEL: beta

- name: dist 압축
env:
TAG: ${{ steps.ver.outputs.tag }}
run: cd dist && zip -r "../dotbugi-${TAG}.zip" .

- name: 프리릴리즈 생성 + zip 첨부
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.ver.outputs.tag }}
run: |
gh release create "$TAG" "dotbugi-${TAG}.zip" \
--repo "$GITHUB_REPOSITORY" \
--title "$TAG" \
--notes "베타(프리릴리즈) 빌드 — main @ ${GITHUB_SHA}" \
--prerelease \
--target "$GITHUB_SHA"

# ── 베타 Chrome Web Store 게시 (기반 — 기본 비활성) ──────────────
# 베타는 별도 스토어 항목이므로 BETA_EXTENSION_ID 사용.
# ※ Chrome manifest version은 숫자만 허용되므로, 스토어 발행을 켤 때는
# `-beta.N` 대신 숫자 스킴(예: x.y.z.N)으로 manifest 버전을 맞춰야 함.
- name: Chrome Web Store 게시 (beta)
if: vars.ENABLE_STORE_PUBLISH == 'true'
uses: mnao305/chrome-extension-upload@4008e29e13c144d0f6725462cbd49b7c291b4928 # v5.0.0
with:
file-path: dotbugi-${{ steps.ver.outputs.tag }}.zip
extension-id: ${{ secrets.BETA_EXTENSION_ID }}
client-id: ${{ secrets.CHROME_CLIENT_ID }}
client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
publish: true

- name: Discord 베타 알림 (노랑)
if: always() && env.DISCORD_WEBHOOK_URL != ''
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
script: |
const webhook = process.env.DISCORD_WEBHOOK_URL;
if (!webhook) return;
const tag = '${{ steps.ver.outputs.tag }}';
const success = '${{ job.status }}' === 'success';
const url = `https://github.com/${context.repo.owner}/${context.repo.repo}/releases/tag/${tag}`;
const res = await fetch(webhook, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
embeds: [{
title: success ? `🚀 베타 릴리즈 ${tag}` : `⚠️ 베타 발행 실패 (${tag})`,
url: success ? url : undefined,
color: success ? 0xfee75c : 0xed4245,
}],
}),
});
if (!res.ok) core.warning(`Discord 알림 실패: ${res.status}`);
118 changes: 118 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: Release Please

# 트렁크 기반 릴리즈: main 머지는 Release PR만 갱신하고,
# 그 Release PR을 머지할 때만 실제 릴리즈/발행이 일어난다.
on:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: release-please
cancel-in-progress: false

jobs:
# ── 1) Release PR 유지 / Release PR 머지 시 태그·릴리즈 생성 ──────────
release-please:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
outputs:
release_created: ${{ steps.rp.outputs.release_created }}
tag_name: ${{ steps.rp.outputs.tag_name }}
steps:
# GitHub App 토큰을 써야 Release PR에 CI(verify/CodeRabbit)가 돈다.
# (GITHUB_TOKEN이 만든 PR/커밋은 다른 워크플로를 트리거하지 않음)
- name: GitHub App 토큰 발급
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Release Please
id: rp
uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
with:
token: ${{ steps.app-token.outputs.token }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json

# ── 2) 릴리즈 생성됨 → 빌드 & 자산 첨부 & (선택)스토어 발행 ──────────
publish:
needs: release-please
if: needs.release-please.outputs.release_created == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: 리포지토리 체크아웃
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false

- name: Node.js 설정
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: npm

- name: 의존성 설치
run: npm ci

- name: 프로덕션 빌드
run: npm run build

- name: dist 압축
env:
TAG: ${{ needs.release-please.outputs.tag_name }}
run: cd dist && zip -r "../dotbugi-${TAG}.zip" .

- name: 릴리즈에 zip 첨부
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ needs.release-please.outputs.tag_name }}
run: gh release upload "$TAG" "dotbugi-${TAG}.zip" --repo "$GITHUB_REPOSITORY" --clobber

# ── Chrome Web Store 자동 게시 (기반 — 기본 비활성) ──────────────
# 활성화: secret(CHROME_CLIENT_ID/SECRET/REFRESH_TOKEN, STABLE_EXTENSION_ID) +
# Variable ENABLE_STORE_PUBLISH=true
- name: Chrome Web Store 게시 (stable)
if: vars.ENABLE_STORE_PUBLISH == 'true'
uses: mnao305/chrome-extension-upload@4008e29e13c144d0f6725462cbd49b7c291b4928 # v5.0.0
with:
file-path: dotbugi-${{ needs.release-please.outputs.tag_name }}.zip
extension-id: ${{ secrets.STABLE_EXTENSION_ID }}
client-id: ${{ secrets.CHROME_CLIENT_ID }}
client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
publish: true

- name: Discord 릴리즈 알림 (스테이블=초록)
if: always() && env.DISCORD_WEBHOOK_URL != ''
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
script: |
const webhook = process.env.DISCORD_WEBHOOK_URL;
if (!webhook) return;
const tag = '${{ needs.release-please.outputs.tag_name }}';
const success = '${{ job.status }}' === 'success';
const url = `https://github.com/${context.repo.owner}/${context.repo.repo}/releases/tag/${tag}`;
const res = await fetch(webhook, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
embeds: [{
title: success ? `✅ 스테이블 릴리즈 ${tag}` : `⚠️ 릴리즈 발행 실패 (${tag})`,
url: success ? url : undefined,
description: success ? '새 버전이 발행되었습니다.' : '워크플로 로그를 확인해주세요.',
color: success ? 0x57f287 : 0xed4245,
}],
}),
});
if (!res.ok) core.warning(`Discord 알림 실패: ${res.status}`);
Loading
Loading