diff --git a/.github/template/release-drafter.yml b/.github/template/release-drafter.yml new file mode 100644 index 0000000..57d307d --- /dev/null +++ b/.github/template/release-drafter.yml @@ -0,0 +1,48 @@ +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' +version-template: $MAJOR.$MINOR.$PATCH + +categories: + - title: '๐Ÿš€ ๊ธฐ๋Šฅ ์ถ”๊ฐ€' + labels: + - 'feat' + - title: 'โ™ป๏ธ ๋ฆฌํŒฉํ† ๋ง' + labels: + - 'refactor' + - title: '๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ •' + labels: + - 'fix' + - title: '๐Ÿงฐ ๊ทธ ์™ธ' + labels: + - 'chore' + - 'ci/cd' + - 'docs' + - 'style' + - 'build' + - 'common' + - 'test' + +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: minor + +exclude-labels: + - 'Release' + +change-template: '- $TITLE (#$NUMBER) - @$AUTHOR' +change-title-escapes: '\\<*_&' + +template: | + ## โœจ ๋ณ€๊ฒฝ ์‚ฌํ•ญ + $CHANGES + + ## ๐Ÿ“ฆ ์ „์ฒด ๋ณ€๊ฒฝ ์ด๋ ฅ + [$PREVIOUS_TAG ~ v$RESOLVED_VERSION]() diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..93a0ed7 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,58 @@ +name: CI/CD Pipeline + +on: + push: + branches: [develop, main] + pull_request: + branches: [develop, main] + +# ๋™์ผํ•œ ๋ธŒ๋žœ์น˜์—์„œ ์ƒˆ๋กœ์šด Push๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด์ „ ์‹คํ–‰์„ ์ทจ์†Œํ•˜์—ฌ ์ž์› ์ ˆ์•ฝ +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install + + - name: Lint + run: pnpm lint + + - name: Build + run: pnpm build + env: + VITE_KAKAO_REST_API_KEY: ${{ secrets.VITE_KAKAO_REST_API_KEY }} + VITE_KAKAO_REDIRECT_URI: ${{ secrets.VITE_KAKAO_REDIRECT_URI }} + VITE_API_BASE_URL: ${{ secrets.VITE_API_BASE_URL }} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000..92a5687 --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,36 @@ +name: Release Drafter + +on: + push: + branches: + - release/* + - main + # PR ์ด๋ฒคํŠธ ์ถ”๊ฐ€๋กœ ์ž๋™ํ™” ๋ฒ”์œ„ ํ™•๋Œ€ + pull_request: + types: [opened, reopened, synchronize] + +permissions: + contents: write + pull-requests: read + +jobs: + update_release_draft: + runs-on: ubuntu-latest + steps: + # Checkout ๋‹จ๊ณ„ ์ œ๊ฑฐ (๋ถˆํ•„์š”ํ•œ ์ž‘์—… ์ƒ๋žต) + - name: Update Draft Release + if: startsWith(github.ref, 'refs/heads/release/') || github.event_name == 'pull_request' + uses: release-drafter/release-drafter@v6 + with: + config-name: template/release-drafter.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Publish Release + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + uses: release-drafter/release-drafter@v6 + with: + config-name: template/release-drafter.yml + publish: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/src/entities/course/model/types.ts b/src/entities/course/model/types.ts index 7d336c4..b293c45 100644 --- a/src/entities/course/model/types.ts +++ b/src/entities/course/model/types.ts @@ -1,9 +1,6 @@ import type {Assignment} from '@/entities/assignment/model/types'; import type {ApiResponse, SemesterCode} from '@/shared/model/common'; -export type {Assignment}; -export type {SemesterCode, SubmissionStatus} from '@/shared/model/common'; - /** * ์ผ์ •(Schedule) ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ */ diff --git a/src/pages/course-overview/ui/AssignmentList.tsx b/src/pages/course-overview/ui/AssignmentList.tsx index 5da79cb..37cf6ff 100644 --- a/src/pages/course-overview/ui/AssignmentList.tsx +++ b/src/pages/course-overview/ui/AssignmentList.tsx @@ -1,6 +1,6 @@ import Badge from '@/shared/ui/Badge'; import {Link} from 'react-router-dom'; -import type {Assignment} from '@/entities/course/model/types'; +import type {Assignment} from '@/entities/assignment/model/types'; interface AssignmentListProps { isOpen?: boolean; diff --git a/src/pages/course-overview/ui/CourseHero.tsx b/src/pages/course-overview/ui/CourseHero.tsx index b0b3a9a..81a7ff7 100644 --- a/src/pages/course-overview/ui/CourseHero.tsx +++ b/src/pages/course-overview/ui/CourseHero.tsx @@ -2,7 +2,8 @@ import snowcodeOverviewMini from '@/assets/images/snowcode_overview_mini.svg'; import {formatCourseTerm} from '@/shared/lib/course'; import CourseActionsBar from './CourseActionsBar'; import {useUserStore} from '@/entities/auth/model/useUserStore'; -import type {CourseOverview, SemesterCode} from '@/entities/course/model/types'; +import type {CourseOverview} from '@/entities/course/model/types'; +import type {SemesterCode} from '@/shared/model/common'; interface CourseHeroProps { courseData: Omit; diff --git a/src/pages/select-assignment/AssignmentSelectPage.tsx b/src/pages/select-assignment/AssignmentSelectPage.tsx index 31847f5..b87ee50 100644 --- a/src/pages/select-assignment/AssignmentSelectPage.tsx +++ b/src/pages/select-assignment/AssignmentSelectPage.tsx @@ -1,6 +1,9 @@ import AssignmentListContainer from './ui/AssignmentListContainer'; import {useState} from 'react'; -import {response, courseOptionsResponse} from '@/shared/mocks/assignmentSelectResponse'; +import { + response, + courseOptionsResponse, +} from '@/shared/mocks/assignmentSelectResponse'; import {useCourseFilter} from '@/features/course/filter-course/lib/useCourseFilter'; import {AssignmentPageLayout} from '@/widgets/assignment-page-layout'; import SelectableItem from '@/shared/ui/SelectableItem'; diff --git a/src/shared/lib/course.ts b/src/shared/lib/course.ts index 7be0cfc..d4eb59c 100644 --- a/src/shared/lib/course.ts +++ b/src/shared/lib/course.ts @@ -1,4 +1,5 @@ -import type {SemesterCode, Unit} from '@/entities/course/model/types'; +import type {Unit} from '@/entities/course/model/types'; +import type {SemesterCode} from '@/shared/model/common'; const SEMESTER_MAP: Record = { FIRST: '1', diff --git a/src/shared/ui/Badge.tsx b/src/shared/ui/Badge.tsx index 5df5d98..493baaf 100644 --- a/src/shared/ui/Badge.tsx +++ b/src/shared/ui/Badge.tsx @@ -84,7 +84,7 @@ const Badge = (props: BadgeProps) => { ); // ์ธ๋ฑ์Šค ๋ฐฐ์ง€ (๋‹จ์›, ๋ฌธ์ œ ๋“ฑ) - case 'index': + case 'index': { const suffix = props.kind === 'unit' ? '๋‹จ์›' : ' ๋ฌธ์ œ'; return ( @@ -93,9 +93,10 @@ const Badge = (props: BadgeProps) => { {suffix} ); + } // ์ œ์ถœ ์ƒํƒœ ๋ฐฐ์ง€ - case 'submission': + case 'submission': { const {label, icon} = SubmissionMeta[props.status!]; return ( @@ -106,6 +107,7 @@ const Badge = (props: BadgeProps) => { {icon} {label} ); + } } }; diff --git a/src/shared/ui/SelectableItem.tsx b/src/shared/ui/SelectableItem.tsx index 7822024..fbcea51 100644 --- a/src/shared/ui/SelectableItem.tsx +++ b/src/shared/ui/SelectableItem.tsx @@ -1,6 +1,6 @@ import {tv, type VariantProps} from 'tailwind-variants'; -export const selectableItemStyles = tv({ +const selectableItemStyles = tv({ base: 'cursor-pointer bg-background w-full flex items-center rounded-[9px] pl-4.5 pr-7.5 py-4 gap-4 border', variants: { selected: {