发布于 2026-01-06 5 阅读
0

如何将你的作品集与 GitHub 代码库同步 😻👌

如何将你的作品集与 GitHub 代码库同步 😻👌

问题🫤

我们(至少大多数人)都有自己的作品集网站。作为开发者,我们都想展示自己参与过的项目,而这些项目大多都存储在我们的 GitHub 个人资料中。

🤔 但是我们如何在作品集网站上展示它们呢?

之前,我用一个ts文件来存储 GitHub 代码库链接和卡片信息,就像这样:

export const data = [
  {
    id: Math.random(),
    subtitle:
      "A Resume Builder with OpenAI that can generate a resume from given data. Supports file upload with Supabase.",
    title: "Resume Builder with OpenAI",
    github: "https://github.com/shricodev/resume-builder-openai",
    noLive: true,
  },
  {
    id: Math.random(),
    title: "PDFWhisper - OpenAI",
    subtitle: "A PDF Chatbot with OpenAI. It can answer questions from a PDF.",
    github: "https://github.com/shricodev/pdfwhisper-openai",
    liveUrl: "https://pdfwhisper-openai.vercel.app/",
  },
  // ...Rest of the project info
];
Enter fullscreen mode Exit fullscreen mode

或者,您也可以使用json文件来存储类似信息。

这种方法的弊端🤨

真正的问题在于这个过程完全是手动操作。而且你也无法显示存储在 README 文件中的项目内容。如果你要创建一个新项目,你需要手动编辑该文件,提交更改,然后将其推送到你的代码仓库。唉,真是太麻烦了😮‍💨。

为什么不实现自动化,并且还可以选择以 Markdown 格式显示README内容呢?


修复方案🛠️

我对这个过程感到很沮丧,也一直觉得我的作品集网站因此显得过时。我首先想到的是:我们能否使用 GitHub Actions 来自动化这个过程?

答案是肯定的……但是如何做到呢?

解决这个问题有几种方法。你可以使用专门用于与 GitHub API 交互的 JavaScript 库(GitHub 推荐Octokit.js),或者寻找其他替代方案。

我阅读文档时,其中提到需要生成个人访问令牌,但我觉得没必要,因为我只需要从公共仓库获取数据。毕竟,GitHub 提供了一个公开 API(https://api.github.com),并且速率限制很宽松,非常适合获取仓库信息。

所以,我决定放弃使用库,改用一些Bash 的魔法。🪄🧙

直接获取数据curl

我使用一个简单的curl命令,获取了仓库中的所有名称:

curl -s "https://api.github.com/users/shricodev/repos?per_page=300" | jq -r '.[] | select(.private == false and .fork == false) | .name' | uniq
Enter fullscreen mode Exit fullscreen mode

此命令会获取给定用户的所有仓库名称。它会使用 `--fork` 过滤掉 fork 的仓库(在大多数情况下,绝对不希望在作品集中显示任何 fork 的仓库)jq,然后根据唯一性筛选项目(只是为了更安全)。

🤔但是我们如何筛选特定的存储库以在我们的网站上显示呢?

为此,我们将向showcase您想要显示的存储库添加一个独特的主题(您可以随意命名,但请将此独特主题添加到您希望在作品集中显示的所有存储库)。

GitHub 仓库主题

现在,我们只需要修改上面的命令jq过滤规则,检查主题是否showcase在存储库中,如果在,则仅获取该存储库的所有元数据和其他信息。

curl -s "https://api.github.com/users/shricodev/repos?per_page=300" | jq -r '.[] | select(.private == false and .fork == false and (.topics | index("showcase") != null)) | .name' | uniq
Enter fullscreen mode Exit fullscreen mode

接下来,我从 GitHub 的开发者设置页面生成了一个个人访问令牌 (PAT),并将其添加到存储库的操作密钥(密钥和变量 -> 操作)中。

看起来是这样的:

添加 GitHub 仓库 PAT 令牌

编写 GitHub Action ✍️

以下是使用上述命令的完整 GitHub Action 工作流程curl

name: Fetch Public Repos README's

on:
  schedule:
    # Run once every single day.
    - cron: '0 0 * * *'
  workflow_dispatch:

permissions:
  contents: write

jobs:
  fetch-readmes:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout the repository
        uses: actions/checkout@v4

      - name: Fetch repository list and README's with metadata
        env:
          TARGET_USER: <username>
          TARGET_FOLDER: '<path_to_the_folder_to_store_readme(s)>'
        run: |
          mkdir -p "$TARGET_FOLDER"

          # Fetch list of public repos
          repos=$(curl -s "https://api.github.com/users/$TARGET_USER/repos?per_page=300" | jq -r '.[] | select(.private == false and .fork == false and (.topics | index("showcase") != null)) | .name' | uniq)

          for repo in $repos; do
            readme_file="$TARGET_FOLDER/${repo}_README.mdx"

            if [[ -f "$readme_file" ]]; then
              echo "README for $repo already exists, skipping..."
              continue
            fi

            repo_metadata=$(curl -s "https://api.github.com/repos/$TARGET_USER/$repo")
            title=$(echo "$repo_metadata" | jq -r '.name')
            description=$(echo "$repo_metadata" | jq -r '.description // ""')
            clone_url=$(echo "$repo_metadata" | jq -r '.clone_url')
            language=$(echo "$repo_metadata" | jq -r '.language // ""')
            homepage=$(echo "$repo_metadata" | jq -r '.homepage // ""')
            topics=$(echo "$repo_metadata" | jq -r '.topics | join(", ")')
            created_at=$(echo "$repo_metadata" | jq -r '.created_at')
            updated_at=$(echo "$repo_metadata" | jq -r '.updated_at')

            status_code=$(curl -o /dev/null -s -w "%{http_code}" https://raw.githubusercontent.com/$TARGET_USER/$repo/main/README.md)

            if [ "$status_code" -eq 200 ]; then
              readme_content=$(curl -s https://raw.githubusercontent.com/$TARGET_USER/$repo/main/README.md)

              {
                echo "---"
                echo "title: "\"$title\"\""
                echo "description: "\"$description\"\""
                echo "clone_url: \"$clone_url\""
                echo "language: \"$language\""
                echo "homepage: \"$homepage\""
                echo "topics:"
                for topic in $(echo "$topics" | tr ',' '\n'); do
                  echo "  - \"$topic\""
                done
                echo "created_at: \"$created_at\""
                echo "updated_at: \"$updated_at\""
                echo "---"
                echo ""
                echo "$readme_content"
              } > "$readme_file"
            else
              echo "No README found for $repo, skipping..."
            fi
          done

      - name: Commit Changes
        run: |
          git config --global user.name "github-actions[bot]"
          git config --global user.email "github-actions[bot]@users.noreply.github.com"

          git add -A

          # Commit if there are any changes
          if ! git diff --cached --quiet; then
            git commit -m "Update READMEs with meta and content from public repos"
            git push https://x-access-token:${{ secrets.<secret_name> }}@github.com/<username>/<repository_name>.git HEAD:<branch_name>
          else
            echo "No changes to commit."
          fi            
Enter fullscreen mode Exit fullscreen mode

GitHub Actions 工作流每天运行,获取用户的所有存储库,写入其元数据和 README 内容(如果有),并将它们保存为<repository_name>_README.mdx文件。

workflow_dispatch:通过在cron 定时器下方添加,我们可以在需要时手动触发工作流。

如果您正在跟着操作,请务必将占位符文本替换为实际名称。

现在,我们有了所有元数据以及存储库 README 内容,我们可以使用任何 Markdown 解析器来解析mdx内容并将其显示在我们的网站上。

想看看我的项目页面实际效果吗?请访问👇

https://techwithshrijal.com/projects


结论⚡

借助这个简单的 GitHub Action,您的作品集网站将始终与您的 GitHub 项目保持同步。我们使用基本的命令行脚本实现了流程自动化,无需依赖第三方库。

您可以在这里找到完整的源代码:https://github.com/shricodev/portfolio.git

请点击这里查看我的作品集:https://techwithshrijal.com

感谢阅读!🎉

莱昂纳多·迪卡普里奥 干杯

文章来源:https://dev.to/shricodev/how-to-sync-your-portfolio-with-github-repositories-2obi