mirror of
https://github.com/rjNemo/fastapi
synced 2026-06-12 13:36:41 +00:00
✨ Add GitHub Action to watch for missing preview docs (#1740)
* 📝 Update release notes * 🔊 Make curl verbose when triggering docs preview * 🔧 Update GitHub Actions circus to use commit hash * ✨ Add PR docs preview watcher
This commit is contained in:
parent
14e7f7c1f4
commit
7032dfb4f1
10 changed files with 135 additions and 5 deletions
2
.github/actions/get-artifact/action.yml
vendored
2
.github/actions/get-artifact/action.yml
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
name: "Deploy Artifact to Netlify"
|
name: "Get Artifact"
|
||||||
description: "Get artifact, possibly uploaded by a PR, useful to deploy docs previews"
|
description: "Get artifact, possibly uploaded by a PR, useful to deploy docs previews"
|
||||||
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||||
inputs:
|
inputs:
|
||||||
|
|
|
||||||
7
.github/actions/watch-previews/Dockerfile
vendored
Normal file
7
.github/actions/watch-previews/Dockerfile
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
FROM python:3.7
|
||||||
|
|
||||||
|
RUN pip install httpx PyGithub "pydantic==1.5.1"
|
||||||
|
|
||||||
|
COPY ./app /app
|
||||||
|
|
||||||
|
CMD ["python", "/app/main.py"]
|
||||||
10
.github/actions/watch-previews/action.yml
vendored
Normal file
10
.github/actions/watch-previews/action.yml
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
name: "Watch docs previews in PRs"
|
||||||
|
description: "Check PRs and trigger new docs deploys"
|
||||||
|
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||||
|
inputs:
|
||||||
|
token:
|
||||||
|
description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: 'docker'
|
||||||
|
image: 'Dockerfile'
|
||||||
94
.github/actions/watch-previews/app/main.py
vendored
Normal file
94
.github/actions/watch-previews/app/main.py
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
from github import Github
|
||||||
|
from github.NamedUser import NamedUser
|
||||||
|
from pydantic import BaseModel, BaseSettings, SecretStr
|
||||||
|
|
||||||
|
github_api = "https://api.github.com"
|
||||||
|
netlify_api = "https://api.netlify.com"
|
||||||
|
|
||||||
|
|
||||||
|
class Settings(BaseSettings):
|
||||||
|
input_token: SecretStr
|
||||||
|
github_repository: str
|
||||||
|
github_event_path: Path
|
||||||
|
github_event_name: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
class Artifact(BaseModel):
|
||||||
|
id: int
|
||||||
|
node_id: str
|
||||||
|
name: str
|
||||||
|
size_in_bytes: int
|
||||||
|
url: str
|
||||||
|
archive_download_url: str
|
||||||
|
expired: bool
|
||||||
|
created_at: datetime
|
||||||
|
updated_at: datetime
|
||||||
|
|
||||||
|
|
||||||
|
class ArtifactResponse(BaseModel):
|
||||||
|
total_count: int
|
||||||
|
artifacts: List[Artifact]
|
||||||
|
|
||||||
|
|
||||||
|
def get_message(commit: str) -> str:
|
||||||
|
return f"Docs preview for commit {commit} at"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
settings = Settings()
|
||||||
|
logging.info(f"Using config: {settings.json()}")
|
||||||
|
g = Github(settings.input_token.get_secret_value())
|
||||||
|
repo = g.get_repo(settings.github_repository)
|
||||||
|
owner: NamedUser = repo.owner
|
||||||
|
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
|
||||||
|
prs = list(repo.get_pulls(state="open"))
|
||||||
|
for pr in prs:
|
||||||
|
logging.info("-----")
|
||||||
|
logging.info(f"Processing PR #{pr.number}: {pr.title}")
|
||||||
|
pr_comments = list(pr.get_issue_comments())
|
||||||
|
pr_commits = list(pr.get_commits())
|
||||||
|
last_commit = pr_commits[0]
|
||||||
|
for pr_commit in pr_commits:
|
||||||
|
if pr_commit.commit.author.date > last_commit.commit.author.date:
|
||||||
|
last_commit = pr_commit
|
||||||
|
commit = last_commit.commit.sha
|
||||||
|
logging.info(f"Last commit: {commit}")
|
||||||
|
message = get_message(commit)
|
||||||
|
notified = False
|
||||||
|
for pr_comment in pr_comments:
|
||||||
|
if message in pr_comment.body:
|
||||||
|
notified = True
|
||||||
|
logging.info(f"Docs preview was notified: {notified}")
|
||||||
|
if not notified:
|
||||||
|
response = httpx.get(
|
||||||
|
f"{github_api}/repos/{settings.github_repository}/actions/artifacts",
|
||||||
|
headers=headers,
|
||||||
|
)
|
||||||
|
data = response.json()
|
||||||
|
artifacts_response = ArtifactResponse.parse_obj(data)
|
||||||
|
use_artifact: Optional[Artifact] = None
|
||||||
|
for artifact in artifacts_response.artifacts:
|
||||||
|
if artifact.name == settings.input_name:
|
||||||
|
use_artifact = artifact
|
||||||
|
break
|
||||||
|
if use_artifact:
|
||||||
|
logging.info(f"Existing artifact: {use_artifact.name}")
|
||||||
|
response = httpx.post(
|
||||||
|
"https://api.github.com/repos/tiangolo/fastapi/actions/workflows/preview-docs.yml/dispatches",
|
||||||
|
headers=headers,
|
||||||
|
json={
|
||||||
|
"ref": "master",
|
||||||
|
"inputs": {"pr": f"{pr.number}", "name": f"docs-zip-{commit}"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
logging.info(
|
||||||
|
f"Trigger sent, response status: {response.status_code} - content: {response.content}"
|
||||||
|
)
|
||||||
|
logging.info("Finished")
|
||||||
2
.github/workflows/build-docs.yml
vendored
2
.github/workflows/build-docs.yml
vendored
|
|
@ -31,7 +31,7 @@ jobs:
|
||||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
run: bash ./scripts/trigger-docs-preview.sh
|
run: bash ./scripts/trigger-docs-preview.sh
|
||||||
- name: Deploy to Netlify
|
- name: Deploy to Netlify
|
||||||
uses: nwtgck/actions-netlify@v1.0.3
|
uses: nwtgck/actions-netlify@v1.1.5
|
||||||
with:
|
with:
|
||||||
publish-dir: './site'
|
publish-dir: './site'
|
||||||
production-branch: master
|
production-branch: master
|
||||||
|
|
|
||||||
6
.github/workflows/preview-docs.yml
vendored
6
.github/workflows/preview-docs.yml
vendored
|
|
@ -8,6 +8,9 @@ on:
|
||||||
name:
|
name:
|
||||||
description: Artifact name for zip file with docs
|
description: Artifact name for zip file with docs
|
||||||
required: true
|
required: true
|
||||||
|
commit:
|
||||||
|
description: Commit SHA hash
|
||||||
|
required: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
|
|
@ -32,8 +35,9 @@ jobs:
|
||||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||||
- name: Comment Deploy
|
- name: Comment Deploy
|
||||||
run: bash ./scripts/docs-comment-deploy.sh
|
|
||||||
env:
|
env:
|
||||||
PR: "${{ github.event.inputs.pr }}"
|
PR: "${{ github.event.inputs.pr }}"
|
||||||
DEPLOY_URL: "${{ steps.netlify.outputs.deploy-url }}"
|
DEPLOY_URL: "${{ steps.netlify.outputs.deploy-url }}"
|
||||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
COMMIT: "${{ github.event.inputs.commit }}"
|
||||||
|
run: bash ./scripts/docs-comment-deploy.sh
|
||||||
|
|
|
||||||
13
.github/workflows/watch-docs-previews.yml
vendored
Normal file
13
.github/workflows/watch-docs-previews.yml
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
name: Deploy Docs
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 * * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/watch-previews
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
## Latest changes
|
## Latest changes
|
||||||
|
|
||||||
|
* Add custom GitHub Action to get artifact with docs preview. PR [#1739](https://github.com/tiangolo/fastapi/pull/1739).
|
||||||
* Add new GitHub Actions to preview docs from PRs. PR [#1738](https://github.com/tiangolo/fastapi/pull/1738).
|
* Add new GitHub Actions to preview docs from PRs. PR [#1738](https://github.com/tiangolo/fastapi/pull/1738).
|
||||||
* Add XML test coverage to support GitHub Actions. PR [#1737](https://github.com/tiangolo/fastapi/pull/1737).
|
* Add XML test coverage to support GitHub Actions. PR [#1737](https://github.com/tiangolo/fastapi/pull/1737).
|
||||||
* Update badges and remove Travis now that GitHub Actions is the main CI. PR [#1736](https://github.com/tiangolo/fastapi/pull/1736).
|
* Update badges and remove Travis now that GitHub Actions is the main CI. PR [#1736](https://github.com/tiangolo/fastapi/pull/1736).
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ set -e
|
||||||
PR=${PR:?Variable not set}
|
PR=${PR:?Variable not set}
|
||||||
DEPLOY_URL=${DEPLOY_URL:?Variable not set}
|
DEPLOY_URL=${DEPLOY_URL:?Variable not set}
|
||||||
GITHUB_TOKEN=${GITHUB_TOKEN:?Variable not set}
|
GITHUB_TOKEN=${GITHUB_TOKEN:?Variable not set}
|
||||||
|
COMMIT=${COMMIT:?Variable not set}
|
||||||
|
|
||||||
curl \
|
curl \
|
||||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
https://api.github.com/repos/tiangolo/fastapi/issues/${PR}/comments \
|
https://api.github.com/repos/tiangolo/fastapi/issues/${PR}/comments \
|
||||||
-d '{"body": "📝 Docs preview: '"${DEPLOY_URL}"'"}'
|
-d '{"body": "📝 Docs preview for commit '"${COMMIT} at: ${DEPLOY_URL}"'"}'
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ fi
|
||||||
NAME=${NAME:?Variable not set}
|
NAME=${NAME:?Variable not set}
|
||||||
GITHUB_TOKEN=${GITHUB_TOKEN:?Variable not set}
|
GITHUB_TOKEN=${GITHUB_TOKEN:?Variable not set}
|
||||||
|
|
||||||
curl \
|
curl -v \
|
||||||
-X POST \
|
-X POST \
|
||||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
-H "Accept: application/vnd.github.v3+json" \
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue