Skip to content

Commit

Permalink
Merge pull request #132 from DDD-Community/feat/#131
Browse files Browse the repository at this point in the history
[feat/#131] 태그 기능 추가, main.yml 원복
  • Loading branch information
lkhoony authored Dec 17, 2024
2 parents 05e8746 + b546bf0 commit 871a5c2
Show file tree
Hide file tree
Showing 17 changed files with 490 additions and 155 deletions.
96 changes: 29 additions & 67 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,8 @@ on:
branches:
- develop
jobs:
build-and-deploy:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, macos-latest]

outputs:
build_outcome: ${{ steps.build_app.outcome }}
deploy_outcome: ${{ steps.deploy_web.outcome }}

build:
runs-on: ubuntu-20.04
steps:
- name: Checkout source code
uses: actions/checkout@v3
Expand All @@ -23,73 +15,44 @@ jobs:
- name: Get commit message and author
id: get_commit_info
run: |
echo "message=$(git log --format=%s -n 1)" >> $GITHUB_OUTPUT
echo "author=$(git log --format=%an -n 1)" >> $GITHUB_OUTPUT
echo "author_username=$(git log --format=%ae -n 1 | cut -d@ -f1)" >> $GITHUB_OUTPUT
echo "::set-output name=message::$(git log --format=%s -n 1)"
echo "::set-output name=author::$(git log --format=%an -n 1)"
echo "::set-output name=author_username::$(git log --format=%ae -n 1 | cut -d@ -f1)"
- name: Install dependencies
run: yarn install

# 웹 빌드 및 S3 업로드 (macOS 환경에서만)
- name: Build Web App
id: build_web
if: matrix.os == 'macos-latest'
- name: Generate build
id: build
env:
VITE_API_BASE_URL: ${{ secrets.VITE_API_BASE_URL }}
VITE_OAUTH_KAKAO_REST_API_KEY: ${{ secrets.VITE_OAUTH_KAKAO_REST_API_KEY }}
VITE_OAUTH_KAKAO_CLIENT_SECRET_CODE: ${{ secrets.VITE_OAUTH_KAKAO_CLIENT_SECRET_CODE }}
VITE_OAUTH_KAKAO_REDIRECT_URI: ${{ secrets.VITE_OAUTH_KAKAO_REDIRECT_URI }}
VITE_DMG_DOWNLOAD_URL: ${{ secrets.VITE_DMG_DOWNLOAD_URL }}
VITE_EXE_DOWNLOAD_URL: ${{ secrets.VITE_EXE_DOWNLOAD_URL }}
run: |
echo "Building web app..."
yarn build
run: yarn build
continue-on-error: true

- name: Upload Web App to AWS S3
id: deploy_web
if: matrix.os == 'macos-latest'
- name: Deploy to S3
id: deploy
if: steps.build.outcome == 'success'
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
echo "Deploying web build to S3..."
aws s3 sync dist/web s3://alignlab-client --delete --region ap-northeast-2
# Electron 빌드 및 GitHub Releases로 Publish
- name: Build and Publish Electron App
id: build_app
env:
VITE_API_BASE_URL: ${{ secrets.VITE_API_BASE_URL }}
VITE_OAUTH_KAKAO_REST_API_KEY: ${{ secrets.VITE_OAUTH_KAKAO_REST_API_KEY }}
VITE_OAUTH_KAKAO_CLIENT_SECRET_CODE: ${{ secrets.VITE_OAUTH_KAKAO_CLIENT_SECRET_CODE }}
VITE_OAUTH_KAKAO_REDIRECT_URI: ${{ secrets.VITE_OAUTH_KAKAO_REDIRECT_URI }}
VITE_DMG_DOWNLOAD_URL: ${{ secrets.VITE_DMG_DOWNLOAD_URL }}
VITE_EXE_DOWNLOAD_URL: ${{ secrets.VITE_EXE_DOWNLOAD_URL }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: yarn electron:publish
aws s3 sync --region ap-northeast-2 dist/web s3://alignlab-client --delete
continue-on-error: true

# CloudFront 캐시 무효화
invalidate-cache:
runs-on: ubuntu-20.04
needs: [build-and-deploy]
if: success()
steps:
- name: Invalidate CloudFront Cache
if: steps.deploy.outcome == 'success'
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
CLOUDFRONT_DISTRIBUTION_ID: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }}
run: |
echo "Invalidating CloudFront cache..."
aws cloudfront create-invalidation --region ap-northeast-2 --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths "/*"
# Discord 알림 - 성공
notify-success:
runs-on: ubuntu-20.04
needs: [build-and-deploy, invalidate-cache]
if: success()
steps:
- name: Discord notification - Success
if: steps.deploy.outcome == 'success'
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_DEPLOY_WEBHOOK }}
DISCORD_USERNAME: GitHub
Expand All @@ -98,28 +61,27 @@ jobs:
with:
args: |
🎉 배포가 성공적으로 완료되었습니다!
다운로드 링크: https://github.com/${{ github.repository }}/releases/latest
웹 앱 링크: https://alignlab.site
브랜치: develop
커밋: ${{ needs.build-and-deploy.outputs.message }}
작성자: ${{ needs.build-and-deploy.outputs.author }}
커밋: ${{ steps.get_commit_info.outputs.message }}
작성자: ${{ steps.get_commit_info.outputs.author }}
# Discord 알림 - 실패
notify-failure:
runs-on: ubuntu-20.04
needs: [build-and-deploy]
if: failure()
steps:
- name: Discord notification - Failure
if: steps.build.outcome == 'failure' || steps.deploy.outcome == 'failure'
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_DEPLOY_WEBHOOK }}
DISCORD_USERNAME: GitHub
DISCORD_AVATAR: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png
uses: Ilshidur/action-discord@master
with:
args: |
❌ ${{ needs.build-and-deploy.outputs.build_outcome == 'failure' && '빌드 중' || '배포 중' }} 오류가 발생했습니다.
❌ ${{ steps.build.outcome == 'failure' && '빌드 중' || '배포 중' }} 오류가 발생했습니다.
브랜치: develop
커밋: ${{ needs.build-and-deploy.outputs.message }}
커밋: ${{ steps.get_commit_info.outputs.message }}
작성자: <@${{ secrets.DISCORD_ID_1 }}>
실패한 워크플로우: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
${{ needs.build-and-deploy.outputs.build_outcome == 'failure' && '빌드 오류 메시지:' || '' }}
${{ needs.build-and-deploy.outputs.build_outcome == 'failure' && needs.build-and-deploy.steps.build_app.outputs.stderr || '' }}
${{ steps.build.outcome == 'failure' && '빌드 오류 메시지:' || '' }}
${{ steps.build.outcome == 'failure' && steps.build.outputs.stderr || '' }}
- name: Check deploy result
if: steps.build.outcome == 'failure' || steps.deploy.outcome == 'failure'
run: exit 1
15 changes: 15 additions & 0 deletions src/api/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface group {
userCapacity?: number
hasJoined?: boolean
ranks?: groupUserRank[]
tagNames?: string[]
}

export interface groupUserRank {
Expand All @@ -41,6 +42,7 @@ export interface groupsReq {
page: number
size: number
sort: sort
keyword: string
}

export interface groupsRes {
Expand Down Expand Up @@ -70,6 +72,10 @@ export interface MyGroupData {
userCount: number
userCapacity: number
ownerNickname: string
ownerUid: number
isHidden: boolean
joinCode?: string
tagNames: string[]
}

export const getGroups = async (groupsReq: groupsReq): Promise<groupsRes> => {
Expand Down Expand Up @@ -128,6 +134,15 @@ export const createGroup = async (group: group): Promise<group> => {
}
}

export const modifyGroup = async (group: group): Promise<group> => {
try {
const res = await axiosInstance.put(`groups/${group.id}`, { ...group })
return res.data.data
} catch (e) {
throw e
}
}

export const getGroupScores = async (groupdId: string | number): Promise<{ data: GroupUserRankData }> => {
try {
const res = await axiosInstance.get(`/group-scores?groupId=${groupdId}`)
Expand Down
11 changes: 11 additions & 0 deletions src/assets/icons/crew-edit-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/assets/icons/crew-search-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 40 additions & 11 deletions src/components/Crew/CrewItem.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
import { group } from "@/api"
import PrivateCrewIcon from "@assets/icons/crew-private-icon.svg?react"
import CrewUserIcon from "@assets/icons/crew-user-icon.svg?react"
import { ReactElement } from "react"
import { ReactElement, useCallback } from "react"

interface CrewItemProps {
group: group
keyword: string
onClickDetail: () => void
}

// 키워드 강조 함수
const highlightKeyword = (text: string | undefined, keyword: string): React.ReactNode => {
if (!text) return null
if (!keyword) return text
const parts = text.split(new RegExp(`(${keyword})`, "gi"))
return parts.map((part, index) =>
part.toLowerCase() === keyword.toLowerCase() ? (
<span key={index} className="text-[#1A75FF]">
{part}
</span>
) : (
part
)
)
}

const CrewItem = (props: CrewItemProps): ReactElement => {
const { group, onClickDetail } = props
const { group, keyword, onClickDetail } = props

const createTags = useCallback(
(tags: string[] | undefined): React.ReactElement[] | null => {
if (!tags || tags.length === 0) return null
return tags.map((tag) => <div key={`${group.id}-tag-${tag}`}>{highlightKeyword(`#${tag}`, keyword)}</div>)
},
[group.id, keyword]
)

return (
<div
Expand All @@ -19,15 +44,19 @@ const CrewItem = (props: CrewItemProps): ReactElement => {
}}
className="flex w-full items-center gap-[24px] bg-white px-[24px] py-[11px] text-[14px] font-semibold leading-[32px]"
>
{/* crew name */}
<div className="flex items-center gap-[6px]">
{group.isHidden && <PrivateCrewIcon />}
<div>{group.name}</div>
</div>
{/* crew user cnt */}
<div className="flex flex-grow items-center gap-[6px]">
<CrewUserIcon />
<div>{`${group.userCount}/${group.userCapacity}명`}</div>
<div className="flex flex-grow items-center gap-[24px]">
{/* crew name */}
<div className="flex items-center gap-[6px]">
{group.isHidden && <PrivateCrewIcon />}
<div>{highlightKeyword(group.name, keyword)}</div>
</div>
{/* crew user cnt */}
<div className="flex items-center gap-[6px]">
<CrewUserIcon />
<div>{`${group.userCount}/${group.userCapacity}명`}</div>
</div>
{/* crew tags */}
{keyword && <div className="flex gap-2.5 text-zinc-400">{createTags(group?.tagNames)}</div>}
</div>
{/* detail button */}
<button
Expand Down
Loading

0 comments on commit 871a5c2

Please sign in to comment.