mirror of https://github.com/tiangolo/fastapi.git
👷♀️ Add script for GitHub Topic Repositories and update External Links (#13135)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
parent
548dd233c3
commit
1b8f823a05
|
|
@ -0,0 +1,40 @@
|
|||
name: Update Topic Repos
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 12 1 * *"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
topic-repos:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install GitHub Actions dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
- name: Update Topic Repos
|
||||
run: python ./scripts/topic_repos.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
|
|
@ -28,9 +28,12 @@ If you have an article, project, tool, or anything related to **FastAPI** that i
|
|||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
## Projects
|
||||
## GitHub Repositories
|
||||
|
||||
Latest GitHub projects with the topic `fastapi`:
|
||||
Most starred GitHub repositories with the topic `fastapi`:
|
||||
|
||||
<div class="github-topic-projects">
|
||||
</div>
|
||||
{% for repo in topic_repos %}
|
||||
|
||||
<a href={{repo.html_url}} target="_blank">★ {{repo.stars}} - {{repo.name}}</a> by <a href={{repo.owner_html_url}} target="_blank">@{{repo.owner_login}}</a>.
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,3 @@
|
|||
const div = document.querySelector('.github-topic-projects')
|
||||
|
||||
async function getDataBatch(page) {
|
||||
const response = await fetch(`https://api.github.com/search/repositories?q=topic:fastapi&per_page=100&page=${page}`, { headers: { Accept: 'application/vnd.github.mercy-preview+json' } })
|
||||
const data = await response.json()
|
||||
return data
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
let page = 1
|
||||
let data = []
|
||||
let dataBatch = await getDataBatch(page)
|
||||
data = data.concat(dataBatch.items)
|
||||
const totalCount = dataBatch.total_count
|
||||
while (data.length < totalCount) {
|
||||
page += 1
|
||||
dataBatch = await getDataBatch(page)
|
||||
data = data.concat(dataBatch.items)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
function setupTermynal() {
|
||||
document.querySelectorAll(".use-termynal").forEach(node => {
|
||||
node.style.display = "block";
|
||||
|
|
@ -158,20 +136,6 @@ async function showRandomAnnouncement(groupId, timeInterval) {
|
|||
}
|
||||
|
||||
async function main() {
|
||||
if (div) {
|
||||
data = await getData()
|
||||
div.innerHTML = '<ul></ul>'
|
||||
const ul = document.querySelector('.github-topic-projects ul')
|
||||
data.forEach(v => {
|
||||
if (v.full_name === 'fastapi/fastapi') {
|
||||
return
|
||||
}
|
||||
const li = document.createElement('li')
|
||||
li.innerHTML = `<a href="${v.html_url}" target="_blank">★ ${v.stargazers_count} - ${v.full_name}</a> by <a href="${v.owner.html_url}" target="_blank">@${v.owner.login}</a>`
|
||||
ul.append(li)
|
||||
})
|
||||
}
|
||||
|
||||
setupTermynal();
|
||||
showRandomAnnouncement('announce-left', 5000)
|
||||
showRandomAnnouncement('announce-right', 10000)
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ plugins:
|
|||
- members: ../en/data/members.yml
|
||||
- sponsors_badge: ../en/data/sponsors_badge.yml
|
||||
- sponsors: ../en/data/sponsors.yml
|
||||
- topic_repos: ../en/data/topic_repos.yml
|
||||
redirects:
|
||||
redirect_maps:
|
||||
deployment/deta.md: deployment/cloud.md
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
import logging
|
||||
import secrets
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
from github import Github
|
||||
from pydantic import BaseModel, SecretStr
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
github_repository: str
|
||||
github_token: SecretStr
|
||||
|
||||
|
||||
class Repo(BaseModel):
|
||||
name: str
|
||||
html_url: str
|
||||
stars: int
|
||||
owner_login: str
|
||||
owner_html_url: str
|
||||
|
||||
|
||||
def main() -> None:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
settings = Settings()
|
||||
|
||||
logging.info(f"Using config: {settings.model_dump_json()}")
|
||||
g = Github(settings.github_token.get_secret_value(), per_page=100)
|
||||
r = g.get_repo(settings.github_repository)
|
||||
repos = g.search_repositories(query="topic:fastapi")
|
||||
repos_list = list(repos)
|
||||
final_repos: list[Repo] = []
|
||||
for repo in repos_list[:100]:
|
||||
if repo.full_name == settings.github_repository:
|
||||
continue
|
||||
final_repos.append(
|
||||
Repo(
|
||||
name=repo.name,
|
||||
html_url=repo.html_url,
|
||||
stars=repo.stargazers_count,
|
||||
owner_login=repo.owner.login,
|
||||
owner_html_url=repo.owner.html_url,
|
||||
)
|
||||
)
|
||||
data = [repo.model_dump() for repo in final_repos]
|
||||
|
||||
# Local development
|
||||
# repos_path = Path("../docs/en/data/topic_repos.yml")
|
||||
repos_path = Path("./docs/en/data/topic_repos.yml")
|
||||
repos_old_content = repos_path.read_text(encoding="utf-8")
|
||||
new_repos_content = yaml.dump(data, sort_keys=False, width=200, allow_unicode=True)
|
||||
if repos_old_content == new_repos_content:
|
||||
logging.info("The data hasn't changed. Finishing.")
|
||||
return
|
||||
repos_path.write_text(new_repos_content, encoding="utf-8")
|
||||
logging.info("Setting up GitHub Actions git user")
|
||||
subprocess.run(["git", "config", "user.name", "github-actions"], check=True)
|
||||
subprocess.run(
|
||||
["git", "config", "user.email", "github-actions@github.com"], check=True
|
||||
)
|
||||
branch_name = f"fastapi-topic-repos-{secrets.token_hex(4)}"
|
||||
logging.info(f"Creating a new branch {branch_name}")
|
||||
subprocess.run(["git", "checkout", "-b", branch_name], check=True)
|
||||
logging.info("Adding updated file")
|
||||
subprocess.run(["git", "add", str(repos_path)], check=True)
|
||||
logging.info("Committing updated file")
|
||||
message = "👥 Update FastAPI GitHub topic repositories"
|
||||
subprocess.run(["git", "commit", "-m", message], check=True)
|
||||
logging.info("Pushing branch")
|
||||
subprocess.run(["git", "push", "origin", branch_name], check=True)
|
||||
logging.info("Creating PR")
|
||||
pr = r.create_pull(title=message, body=message, base="master", head=branch_name)
|
||||
logging.info(f"Created PR: {pr.number}")
|
||||
logging.info("Finished")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue