Skip to content
Draft
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
13 changes: 13 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -34,6 +36,17 @@ jobs:
git diff --staged --quiet || git commit -m "Update blogcard OGP cache [skip ci]"
git push

- name: Fetch GitHub activity data
run: npm run fetch-github-activity
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Commit and push GitHub activity data
run: |
git add data/github_activity.json
git diff --staged --quiet || git commit -m "Update GitHub activity data [skip ci]"
git push

- name: Generate OGP images
run: npm run generate-ogp

Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/update-github-activity.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Update GitHub Activity

on:
schedule:
# 30分ごとに実行
- cron: '*/30 * * * *'
workflow_dispatch: # 手動実行も可能

jobs:
update-activity:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.18.1'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Fetch GitHub activity
run: npm run fetch-github-activity
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Commit and push activity data
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add data/github_activity.json
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "Update GitHub activity data (scheduled)"
git push
fi
3 changes: 3 additions & 0 deletions content/activity/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
title: "Activity"
---
12 changes: 12 additions & 0 deletions data/github_activity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"recentPRs": [],
"stats": {
"totalMergedInOwnRepos": 0,
"totalMergedInOtherRepos": 0,
"byRepo": {
"byStars": [],
"byMergeCount": []
}
},
"lastUpdated": null
}
4 changes: 4 additions & 0 deletions hugo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ ignoreFiles = [
# 他の候補: Life Log / Side Notes / Misc / Personal Notes / Journal
name = "_misc"
url = "/tags/diary/"
[[languages.ja.menu.main]]
identifier = "activity"
name = "activity"
url = "/activity"
[[languages.ja.menu.main]]
identifier = "about"
name = "about"
Expand Down
104 changes: 104 additions & 0 deletions layouts/activity/list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{{ define "main" }}
{{ $data := site.Data.github_activity }}
<div class="activity-page">
{{ if $data }}

{{/* 統計サマリー */}}
<section class="activity-section">
<h2>stats</h2>
<div class="activity-stats-grid">
<div class="activity-stat-card">
<span class="activity-stat-value">{{ add $data.stats.totalMergedInOwnRepos $data.stats.totalMergedInOtherRepos }}</span>
<span class="activity-stat-label">merged PRs(合計)</span>
</div>
<div class="activity-stat-card">
<span class="activity-stat-value">{{ $data.stats.totalMergedInOwnRepos }}</span>
<span class="activity-stat-label">自分のリポジトリ</span>
</div>
<div class="activity-stat-card">
<span class="activity-stat-value">{{ $data.stats.totalMergedInOtherRepos }}</span>
<span class="activity-stat-label">他のリポジトリ</span>
</div>
</div>
</section>

{{/* 直近50件のPR */}}
<section class="activity-section">
<h2>recent PRs</h2>
<div class="activity-filter-bar" id="pr-filter-bar">
<button class="activity-filter-btn active" data-filter="all">すべて</button>
<button class="activity-filter-btn" data-filter="own">自分のリポジトリのみ</button>
<button class="activity-filter-btn" data-filter="other">外部コントリビューションのみ</button>
</div>
<div class="activity-pr-list" id="pr-list">
{{ range $data.recentPRs }}
<article class="activity-pr-card" data-own-repo="{{ .isOwnRepo }}">
<div class="activity-pr-card-header">
<a href="{{ .url }}" class="activity-pr-title" target="_blank" rel="noopener noreferrer">{{ .title }}</a>
<a href="https://github.com/{{ .repo }}" class="activity-pr-repo" target="_blank" rel="noopener noreferrer">{{ .repo }}</a>
</div>
<div class="activity-pr-meta">
{{ if .mergedAt }}
<time class="activity-pr-date" datetime="{{ .mergedAt }}">{{ .mergedAt }}</time>
{{ end }}
<span class="activity-pr-badge {{ if .isOwnRepo }}activity-pr-badge--own{{ else }}activity-pr-badge--other{{ end }}">
{{ if .isOwnRepo }}own{{ else }}contrib{{ end }}
</span>
</div>
{{ if .summary }}
<p class="activity-pr-summary">{{ .summary }}</p>
{{ end }}
</article>
{{ end }}
{{ if not $data.recentPRs }}
<p class="activity-empty">PRデータを取得中です。しばらくお待ちください。</p>
{{ end }}
</div>
</section>

{{/* リポジトリ別統計 */}}
<section class="activity-section">
<h2>repos</h2>
<div class="activity-sort-bar" id="repo-sort-bar">
<button class="activity-sort-btn active" data-sort="stars">★ スター順</button>
<button class="activity-sort-btn" data-sort="count">↑ マージ数順</button>
</div>

{{/*
データをJS側に渡す。
jsonify はGoのencoding/jsonを使用し、< > & などの特殊文字をUnicodeエスケープ(\u003cなど)に変換するため
</script>等の文字列を含んでいてもXSSのリスクはない。
safeJS はHugoテンプレートエンジンが<script>内でJSONを二重エンコードしないようにするためのもの。
*/}}
<script id="repo-data" type="application/json">{{ $data.stats.byRepo | jsonify | safeJS }}</script>

<div class="activity-repo-list" id="repo-list">
{{/* 初期描画: スター順 */}}
{{ range $data.stats.byRepo.byStars }}
<div class="activity-repo-item">
<a href="{{ .repoUrl }}" class="activity-repo-name" target="_blank" rel="noopener noreferrer">{{ .repo }}</a>
<div class="activity-repo-meta">
<span class="activity-repo-stars">★ {{ .stars }}</span>
<span class="activity-repo-count">{{ .mergedCount }} PRs</span>
</div>
</div>
{{ end }}
{{ if not $data.stats.byRepo.byStars }}
<p class="activity-empty">データを取得中です。しばらくお待ちください。</p>
{{ end }}
</div>
</section>

{{ if $data.lastUpdated }}
<footer class="activity-footer">
<time class="activity-last-updated" datetime="{{ $data.lastUpdated }}">最終更新: {{ $data.lastUpdated }}</time>
</footer>
{{ end }}

{{ else }}
<p class="activity-empty">データを取得中です。しばらくお待ちください。</p>
{{ end }}
</div>

<script src="{{ "activity.js" | absURL }}"></script>
{{ end }}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"generate-ogp": "node scripts/generate-ogp.mjs",
"fetch-blogcard-ogp": "node scripts/fetch-blogcard-ogp.mjs",
"fetch-speakerdeck-oembed": "node scripts/fetch-speakerdeck-oembed.mjs",
"fetch-github-activity": "node scripts/fetch-github-activity.mjs",
"fetch-all-cache": "npm run fetch-blogcard-ogp && npm run fetch-speakerdeck-oembed"
},
"keywords": [],
Expand Down
Loading