test #14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Stats | |
| on: | |
| push: | |
| paths: | |
| - 'content/**' | |
| - '.github/workflows/build-stats.yml' | |
| workflow_dispatch: # 수동 실행도 가능하도록 | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-stats: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Count files and generate stats | |
| run: | | |
| echo "Counting files in content directories..." | |
| # 각 카테고리별 파일/폴더 개수 계산 | |
| POST_COUNT=$(find content/post -name "*.md" | wc -l) | |
| PROJECT_COUNT=$(find content/project -name "*.md" | wc -l) | |
| STUDY_COUNT=$(find content/study -name "*.md" | wc -l) | |
| # Post 파일 중에서 Retrospect 태그가 있는 파일 개수 계산 | |
| RETROSPECT_COUNT=$(grep -l "tags.*retrospect\|tags.*Retrospect" content/post/*.md 2>/dev/null | wc -l) | |
| echo "Post: $POST_COUNT" | |
| echo "Project: $PROJECT_COUNT" | |
| echo "Study: $STUDY_COUNT" | |
| echo "Retrospect: $RETROSPECT_COUNT" | |
| # JSON 파일 생성 | |
| cat > data/stats.json << EOF | |
| { | |
| "post": $POST_COUNT, | |
| "project": $PROJECT_COUNT, | |
| "study": $STUDY_COUNT, | |
| "retrospect": $RETROSPECT_COUNT, | |
| "lastUpdated": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" | |
| } | |
| EOF | |
| echo "Stats file generated:" | |
| cat data/stats.json | |
| - name: Generate study categories | |
| if: contains(github.event.head_commit.modified, 'content/study/') || contains(github.event.head_commit.added, 'content/study/') || contains(github.event.head_commit.removed, 'content/study/') || github.event_name == 'workflow_dispatch' | |
| run: | | |
| echo "Generating study categories from folder structure..." | |
| # Study 폴더 구조 분석 | |
| STUDY_CATEGORIES=$(find content/study -maxdepth 1 -type d | tail -n +2 | sed 's|content/study/||') | |
| # JSON 구조 생성 | |
| cat > data/study-categories.json << 'EOF' | |
| { | |
| "categories": [ | |
| EOF | |
| # 각 대분류 카테고리 처리 | |
| first=true | |
| for category in $STUDY_CATEGORIES; do | |
| if [ "$first" = true ]; then | |
| first=false | |
| else | |
| echo "," >> data/study-categories.json | |
| fi | |
| # 카테고리 이름 자동 변환 (하이픈/언더스코어를 공백으로, 첫 글자 대문자) | |
| name=$(echo $category | sed 's/-/ /g' | sed 's/_/ /g' | sed 's/\b\w/\U&/g') | |
| # 서브카테고리 찾기 | |
| subcategories=$(find content/study/$category -maxdepth 1 -type d | tail -n +2 | sed "s|content/study/$category/||") | |
| cat >> data/study-categories.json << EOF | |
| { | |
| "name": "$name", | |
| "slug": "$category", | |
| "tags": ["$name"], | |
| "hasSubcategories": true, | |
| "subcategories": [ | |
| EOF | |
| # 서브카테고리 처리 | |
| first_sub=true | |
| for subcategory in $subcategories; do | |
| if [ "$first_sub" = true ]; then | |
| first_sub=false | |
| else | |
| echo "," >> data/study-categories.json | |
| fi | |
| # 서브카테고리 이름 자동 변환 | |
| subname=$(echo $subcategory | sed 's/-/ /g' | sed 's/_/ /g' | sed 's/\b\w/\U&/g') | |
| cat >> data/study-categories.json << EOF | |
| { | |
| "name": "$subname", | |
| "slug": "$subcategory" | |
| } | |
| EOF | |
| done | |
| cat >> data/study-categories.json << EOF | |
| ] | |
| } | |
| EOF | |
| done | |
| cat >> data/study-categories.json << EOF | |
| ], | |
| "lastUpdated": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" | |
| } | |
| EOF | |
| echo "Study categories file generated:" | |
| cat data/study-categories.json | |
| - name: Generate projects | |
| if: contains(github.event.head_commit.modified, 'content/project/') || contains(github.event.head_commit.added, 'content/project/') || contains(github.event.head_commit.removed, 'content/project/') || github.event_name == 'workflow_dispatch' | |
| run: | | |
| echo "Generating projects from content files..." | |
| # 프로젝트 정보 수집 | |
| echo "Collecting project information..." | |
| cat > data/projects.json << 'EOF' | |
| { | |
| "projects": [ | |
| EOF | |
| # 모든 프로젝트 파일 찾기 | |
| first_project=true | |
| project_files=$(find content/project -name "*.md" -type f) | |
| for project_file in $project_files; do | |
| if [ -f "$project_file" ]; then | |
| if [ "$first_project" = true ]; then | |
| first_project=false | |
| else | |
| echo "," >> data/projects.json | |
| fi | |
| # 파일명에서 slug 추출 | |
| filename=$(basename "$project_file" .md) | |
| # 프로젝트 정보 파싱 (frontmatter에서 추출) | |
| project_name=$(grep "^title:" "$project_file" | sed 's/^title: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| short_description=$(grep "^description:" "$project_file" | sed 's/^description: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| period=$(grep "^period:" "$project_file" | sed 's/^period: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| team_size=$(grep "^teamSize:" "$project_file" | sed 's/^teamSize: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| role=$(grep "^role:" "$project_file" | sed 's/^role: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| achievement=$(grep "^achievements:" "$project_file" | sed 's/^achievements: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| tags=$(grep "^tags:" "$project_file" | sed 's/^tags: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| date=$(grep "^date:" "$project_file" | sed 's/^date: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| # 프로젝트 상세 내용 추출 (## 프로젝트 상세 내용 섹션 이후) | |
| details_section=$(sed -n '/## 프로젝트 상세 내용/,$p' "$project_file" | sed '1d' | sed '/^## /q' | sed '$d' | grep -v '^$' | sed 's/^- //') | |
| details_array=$(echo "$details_section" | sed 's/^/"/; s/$/"/' | tr '\n' ',' | sed 's/,$//') | |
| cat >> data/projects.json << EOF | |
| { | |
| "name": "$project_name", | |
| "title": "$project_name", | |
| "description": "$short_description", | |
| "period": "$period", | |
| "teamSize": "$team_size", | |
| "role": "$role", | |
| "achievements": "$achievement", | |
| "tags": "$tags", | |
| "date": "$date", | |
| "image": "image/${filename}.svg", | |
| "slug": "$filename", | |
| "details": [$details_array] | |
| } | |
| EOF | |
| fi | |
| done | |
| cat >> data/projects.json << EOF | |
| ], | |
| "lastUpdated": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" | |
| } | |
| EOF | |
| echo "Projects file generated:" | |
| cat data/projects.json | |
| - name: Generate posts | |
| if: contains(github.event.head_commit.modified, 'content/post/') || contains(github.event.head_commit.added, 'content/post/') || contains(github.event.head_commit.removed, 'content/post/') || github.event_name == 'workflow_dispatch' | |
| run: | | |
| # 포스트 정보 수집 (Post + Retrospect 통합) | |
| echo "Collecting post information..." | |
| cat > data/posts.json << 'EOF' | |
| { | |
| "posts": [ | |
| EOF | |
| # 모든 포스트 파일 찾기 (Post + Retrospect) | |
| first_post=true | |
| post_files=$(find content/post -name "*.md" -type f) | |
| for post_file in $post_files; do | |
| if [ -f "$post_file" ]; then | |
| if [ "$first_post" = true ]; then | |
| first_post=false | |
| else | |
| echo "," >> data/posts.json | |
| fi | |
| # 파일명에서 slug 추출 | |
| filename=$(basename "$post_file" .md) | |
| # frontmatter 파싱 | |
| title=$(grep "^title:" "$post_file" | sed 's/^title: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| description=$(grep "^description:" "$post_file" | sed 's/^description: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| date=$(grep "^date:" "$post_file" | sed 's/^date: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| tags=$(grep "^tags:" "$post_file" | sed 's/^tags: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| image=$(grep "^image:" "$post_file" | sed 's/^image: //' | sed 's/^"//; s/"$//' | tr -d '\n') | |
| # 기본값 설정 | |
| [ -z "$title" ] && title="$filename" | |
| [ -z "$description" ] && description="" | |
| [ -z "$date" ] && date="$(date +%Y-%m-%d)" | |
| [ -z "$tags" ] && tags="[]" | |
| [ -z "$image" ] && image="" | |
| cat >> data/posts.json << EOF | |
| { | |
| "slug": "$filename", | |
| "title": "$title", | |
| "description": "$description", | |
| "date": "$date", | |
| "tags": "$tags", | |
| "image": "$image" | |
| } | |
| EOF | |
| fi | |
| done | |
| cat >> data/posts.json << EOF | |
| ], | |
| "lastUpdated": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" | |
| } | |
| EOF | |
| echo "Posts file generated:" | |
| cat data/posts.json | |
| - name: Commit and push changes | |
| run: | | |
| git config --local user.email "[email protected]" | |
| git config --local user.name "GitHub Action" | |
| # 원격 저장소에서 최신 변경사항 가져오기 | |
| git stash | |
| git pull origin main --rebase | |
| git stash pop | |
| # 변경사항 스테이징 및 커밋 | |
| git add data/stats.json | |
| # 조건부로 파일 추가 | |
| if [[ "${{ github.event.head_commit.modified }}" == *"content/study/"* ]] || [[ "${{ github.event.head_commit.added }}" == *"content/study/"* ]] || [[ "${{ github.event.head_commit.removed }}" == *"content/study/"* ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| git add data/study-categories.json | |
| fi | |
| if [[ "${{ github.event.head_commit.modified }}" == *"content/project/"* ]] || [[ "${{ github.event.head_commit.added }}" == *"content/project/"* ]] || [[ "${{ github.event.head_commit.removed }}" == *"content/project/"* ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| git add data/projects.json | |
| fi | |
| if [[ "${{ github.event.head_commit.modified }}" == *"content/post/"* ]] || [[ "${{ github.event.head_commit.added }}" == *"content/post/"* ]] || [[ "${{ github.event.head_commit.removed }}" == *"content/post/"* ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| git add data/posts.json | |
| fi | |
| # 변경사항이 있는 경우에만 커밋 | |
| if ! git diff --staged --quiet; then | |
| git commit -m "Update stats and categories [skip ci]" | |
| git push origin main | |
| else | |
| echo "No changes to commit" | |
| fi |