]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
✨ Add instant docs deploy previews for PRs from forks (#2244)
authorSebastián Ramírez <tiangolo@gmail.com>
Sun, 25 Oct 2020 17:54:36 +0000 (18:54 +0100)
committerGitHub <noreply@github.com>
Sun, 25 Oct 2020 17:54:36 +0000 (18:54 +0100)
* 🔥 Disable action Watch Docs Previews

* 🔧 Use predefined name for docs artifacts for previews

* ✨ Add new GitHub Action Comment Docs Preview in PR

* 🔧 Refactor GitHub Action Preview Docs to work as workflow_run using new action to extract where to comment

.github/actions/comment-docs-preview-in-pr/Dockerfile [new file with mode: 0644]
.github/actions/comment-docs-preview-in-pr/action.yml [new file with mode: 0644]
.github/actions/comment-docs-preview-in-pr/app/main.py [new file with mode: 0644]
.github/workflows/build-docs.yml
.github/workflows/preview-docs.yml
.github/workflows/watch-docs-previews.yml

diff --git a/.github/actions/comment-docs-preview-in-pr/Dockerfile b/.github/actions/comment-docs-preview-in-pr/Dockerfile
new file mode 100644 (file)
index 0000000..4f20c5f
--- /dev/null
@@ -0,0 +1,7 @@
+FROM python:3.7
+
+RUN pip install httpx "pydantic==1.5.1" pygithub
+
+COPY ./app /app
+
+CMD ["python", "/app/main.py"]
diff --git a/.github/actions/comment-docs-preview-in-pr/action.yml b/.github/actions/comment-docs-preview-in-pr/action.yml
new file mode 100644 (file)
index 0000000..0eb6440
--- /dev/null
@@ -0,0 +1,13 @@
+name: Comment Docs Preview in PR
+description: Comment with the docs URL preview in the PR
+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
+  deploy_url:
+    description: The deployment URL to comment in the PR
+    required: true
+runs:
+  using: docker
+  image: Dockerfile
diff --git a/.github/actions/comment-docs-preview-in-pr/app/main.py b/.github/actions/comment-docs-preview-in-pr/app/main.py
new file mode 100644 (file)
index 0000000..3b10e0e
--- /dev/null
@@ -0,0 +1,70 @@
+import logging
+import sys
+from pathlib import Path
+from typing import Optional
+
+import httpx
+from github import Github
+from github.PullRequest import PullRequest
+from pydantic import BaseModel, BaseSettings, SecretStr, ValidationError
+
+github_api = "https://api.github.com"
+
+
+class Settings(BaseSettings):
+    github_repository: str
+    github_event_path: Path
+    github_event_name: Optional[str] = None
+    input_token: SecretStr
+    input_deploy_url: str
+
+
+class PartialGithubEventHeadCommit(BaseModel):
+    id: str
+
+
+class PartialGithubEventWorkflowRun(BaseModel):
+    head_commit: PartialGithubEventHeadCommit
+
+
+class PartialGithubEvent(BaseModel):
+    workflow_run: PartialGithubEventWorkflowRun
+
+
+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)
+    try:
+        event = PartialGithubEvent.parse_file(settings.github_event_path)
+    except ValidationError as e:
+        logging.error(f"Error parsing event file: {e.errors()}")
+        sys.exit(0)
+    use_pr: Optional[PullRequest] = None
+    for pr in repo.get_pulls():
+        if pr.head.sha == event.workflow_run.head_commit.id:
+            use_pr = pr
+            break
+    if not use_pr:
+        logging.error(
+            f"No PR found for hash: {event.workflow_run.head_commit.id}"
+        )
+        sys.exit(0)
+    github_headers = {
+        "Authorization": f"token {settings.input_token.get_secret_value()}"
+    }
+    url = f"{github_api}/repos/{settings.github_repository}/issues/{use_pr.number}/comments"
+    logging.info(f"Using comments URL: {url}")
+    response = httpx.post(
+        url,
+        headers=github_headers,
+        json={
+            "body": f"📝 Docs preview for commit {use_pr.head.sha} at: {settings.input_deploy_url}"
+        },
+    )
+    if not (200 <= response.status_code <= 300):
+        logging.error(f"Error posting comment: {response.text}")
+        sys.exit(1)
+    logging.info("Finished")
index ad0ff73a066a4fa556e561c6727a8707d2f4c6f1..bcb4e373ec334fe7b3b5501d89d7c52132e5ec99 100644 (file)
@@ -28,7 +28,7 @@ jobs:
       - uses: actions/upload-artifact@v2
         if: github.event_name == 'pull_request'
         with:
-          name: docs-zip-${{ github.event.pull_request.head.sha }}
+          name: docs-zip
           path: ./docs.zip
       - name: Deploy to Netlify
         uses: nwtgck/actions-netlify@v1.1.5
index 3d48a2f75cee648ac07758636a99e8d34a30ab61..f5c20c966837c6a9cd47193d0bd131707b0cbb23 100644 (file)
@@ -1,29 +1,41 @@
 name: Preview Docs
 on:
-  workflow_dispatch:
-    inputs:
-      pr:
-        description: Pull Request number
-        required: true
-      name:
-        description: Artifact name for zip file with docs
-        required: true
-      commit:
-        description: Commit SHA hash
-        required: true
+  workflow_run:
+    workflows:
+      - Build Docs
+    types: 
+      - completed
+  # workflow_dispatch:
+  #   inputs:
+  #     pr:
+  #       description: Pull Request number
+  #       required: true
+  #     name:
+  #       description: Artifact name for zip file with docs
+  #       required: true
+  #     commit:
+  #       description: Commit SHA hash
+  #       required: true
 
 jobs:
   deploy:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v2
-      - uses: ./.github/actions/get-artifact
+      # - uses: ./.github/actions/get-artifact
+      #   with:
+      #     token: ${{ secrets.GITHUB_TOKEN }}
+      #     name: ${{ github.event.inputs.name }}
+      #     path: ./archive.zip
+      # - name: Unzip docs
+      #   run: bash ./scripts/unzip-docs.sh
+      - name: Download Artifact Docs
+        uses: dawidd6/action-download-artifact@v2.9.0
         with:
-          token: ${{ secrets.GITHUB_TOKEN }}
-          name: ${{ github.event.inputs.name }}
-          path: ./archive.zip
-      - name: Unzip docs
-        run: bash ./scripts/unzip-docs.sh
+          github_token: ${{ secrets.GITHUB_TOKEN }}
+          workflow: build-docs.yml
+          run_id: ${{ github.event.workflow_run.id }}
+          name: docs-zip
       - name: Deploy to Netlify
         id: netlify
         uses: nwtgck/actions-netlify@v1.1.5
@@ -36,9 +48,7 @@ jobs:
           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
       - name: Comment Deploy
-        env:
-          PR: "${{ github.event.inputs.pr }}"
-          DEPLOY_URL: "${{ steps.netlify.outputs.deploy-url }}"
-          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
-          COMMIT: "${{ github.event.inputs.commit }}"
-        run: bash ./scripts/docs-comment-deploy.sh
+        uses: ./.github/actions/comment-docs-preview-in-pr
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          deploy_url: "${{ steps.netlify.outputs.deploy-url }}"
index c8a0158cc0c7cf10e8c421bea3cbc831ef5b4e25..fea49cdbe3f13b9a0d9a377fdf162009c9b400d0 100644 (file)
@@ -1,13 +1,13 @@
-name: Watch Docs Previews
-on:
-  schedule:
-    - cron: "0 * * * *"
+name: Watch Docs Previews
+on:
+  schedule:
+    - cron: "0 * * * *"
 
-jobs:
-  deploy:
-    runs-on: ubuntu-18.04
-    steps:
-      - uses: actions/checkout@v2
-      - uses: ./.github/actions/watch-previews
-        with:
-          token: ${{ secrets.ACTIONS_TOKEN }}
+jobs:
+  deploy:
+    runs-on: ubuntu-18.04
+    steps:
+      - uses: actions/checkout@v2
+      - uses: ./.github/actions/watch-previews
+        with:
+          token: ${{ secrets.ACTIONS_TOKEN }}