aboutsummaryrefslogtreecommitdiffstats
path: root/static-builds
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2022-07-12 09:52:06 +0400
committerGravatar Hassan Abouelela <[email protected]>2022-07-12 14:54:34 +0400
commit0404e0040a0a6fc4f4520bfdc14b800390800382 (patch)
treea38743b58d056d6ce9af7afc865988db72792511 /static-builds
parentAdd GitHub Artifact API View (diff)
Update Netlify Build Script
Update the netlify build script to use the artifacts API from the site. Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'static-builds')
-rw-r--r--static-builds/README.md24
-rw-r--r--static-builds/netlify_build.py125
2 files changed, 45 insertions, 104 deletions
diff --git a/static-builds/README.md b/static-builds/README.md
index 9b86ed08..a3c7962b 100644
--- a/static-builds/README.md
+++ b/static-builds/README.md
@@ -27,16 +27,29 @@ Alternatively, you can use the [Dockerfile](/Dockerfile) and extract the build.
Both output their builds to a `build/` directory.
### Deploying To Netlify
-To deploy to netlify, link your site GitHub repository to a netlify site, and use the following settings:
+To deploy to netlify, link your site GitHub repository to a netlify site, and use the settings below.
+The netlify build script uses the site API to fetch and download the artifact, using a GitHub app that
+can access the repo. The app must have the `actions` and `artifacts` scopes enabled.
+### Netlify Settings
Build Command:
-`python -m pip install httpx==0.19.0 && python static-builds/netlify_build.py`
+`python -m pip install httpx==0.23.0 && python static-builds/netlify_build.py`
Publish Directory:
`build`
-Environment Variables:
-- PYTHON_VERSION: 3.8
+**Environment Variables**
+
+| Name | Value | Description |
+|----------------|--------------------------------|-------------------------------------------------------------------------------------------|
+| PYTHON_VERSION | 3.8 | The python version. Supported options are defined by netlify [here][netlify build image]. |
+| API_URL | https://pythondiscord.com/ | The link to the API, which will be used to fetch the build artifacts. |
+| ACTION_NAME | Build & Publish Static Preview | The name of the workflow which will be used to find the artifact. |
+| ARTIFACT_NAME | static-build | The name of the artifact to download. |
+
+
+[netlify build image]: https://github.com/netlify/build-image/tree/focal
+
Note that at this time, if you are deploying to netlify yourself, you won't have access to the
@@ -45,6 +58,3 @@ You can either update the pack to one which will work on your domain, or you'll
> Warning: If you are modifying the [build script](./netlify_build.py), make sure it is compatible with Python 3.8.
-
-Note: The build script uses [nightly.link](https://github.com/oprypin/nightly.link)
-to fetch the artifact with no authentication.
diff --git a/static-builds/netlify_build.py b/static-builds/netlify_build.py
index 4e1e6106..13cd0279 100644
--- a/static-builds/netlify_build.py
+++ b/static-builds/netlify_build.py
@@ -4,106 +4,42 @@
# This script performs all the actions required to build and deploy our project on netlify
# It depends on the following packages, which are set in the netlify UI:
-# httpx == 0.19.0
+# httpx == 0.23.0
+import json
import os
-import time
-import typing
import zipfile
from pathlib import Path
from urllib import parse
import httpx
-API_URL = "https://api.github.com"
-NIGHTLY_URL = "https://nightly.link"
-OWNER, REPO = parse.urlparse(os.getenv("REPOSITORY_URL")).path.lstrip("/").split("/")[0:2]
-
-
-def get_build_artifact() -> typing.Tuple[int, str]:
- """
- Search for a build artifact, and return the result.
-
- The return is a tuple of the check suite ID, and the URL to the artifacts.
- """
- print("Fetching build URL.")
-
- if os.getenv("PULL_REQUEST").lower() == "true":
- print(f"Fetching data for PR #{os.getenv('REVIEW_ID')}")
-
- pull_url = f"{API_URL}/repos/{OWNER}/{REPO}/pulls/{os.getenv('REVIEW_ID')}"
- pull_request = httpx.get(pull_url)
- pull_request.raise_for_status()
-
- commit_sha = pull_request.json()["head"]["sha"]
-
- workflows_params = parse.urlencode({
- "event": "pull_request",
- "per_page": 100
- })
-
- else:
- commit_sha = os.getenv("COMMIT_REF")
-
- workflows_params = parse.urlencode({
- "event": "push",
- "per_page": 100
- })
-
- print(f"Fetching action data for commit {commit_sha}")
-
- workflows = httpx.get(f"{API_URL}/repos/{OWNER}/{REPO}/actions/runs?{workflows_params}")
- workflows.raise_for_status()
-
- for run in workflows.json()["workflow_runs"]:
- if run["name"] == "Build & Publish Static Preview" and commit_sha == run["head_sha"]:
- print(f"Found action for this commit: {run['id']}\n{run['html_url']}")
- break
- else:
- raise Exception("Could not find the workflow run for this event.")
-
- polls = 0
- while polls <= 20:
- if run["status"] != "completed":
- print("Action isn't ready, sleeping for 10 seconds.")
- polls += 1
- time.sleep(10)
-
- elif run["conclusion"] != "success":
- print("Aborting build due to a failure in a previous CI step.")
- exit(0)
-
- else:
- print(f"Found artifact URL:\n{run['artifacts_url']}")
- return run["check_suite_id"], run["artifacts_url"]
-
- _run = httpx.get(run["url"])
- _run.raise_for_status()
- run = _run.json()
-
- raise Exception("Polled for the artifact workflow, but it was not ready in time.")
-
-
-def download_artifact(suite_id: int, url: str) -> None:
- """Download a build artifact from `url`, and unzip the content."""
- print("Fetching artifact data.")
-
- artifacts = httpx.get(url)
- artifacts.raise_for_status()
- artifacts = artifacts.json()
-
- if artifacts["total_count"] == "0":
- raise Exception(f"No artifacts were found for this build, aborting.\n{url}")
-
- for artifact in artifacts["artifacts"]:
- if artifact["name"] == "static-build":
- print("Found artifact with build.")
- break
- else:
- raise Exception("Could not find an artifact with the expected name.")
-
- artifact_url = f"{NIGHTLY_URL}/{OWNER}/{REPO}/suites/{suite_id}/artifacts/{artifact['id']}"
- zipped_content = httpx.get(artifact_url)
+if __name__ == "__main__":
+ owner, repo = parse.urlparse(os.getenv("REPOSITORY_URL")).path.lstrip("/").split("/")[0:2]
+
+ download_url = "/".join([
+ os.getenv("API_URL").rstrip("/"),
+ "api/github/artifact",
+ owner,
+ repo,
+ os.getenv("COMMIT_REF"),
+ parse.quote(os.getenv("ACTION_NAME")),
+ os.getenv("ARTIFACT_NAME"),
+ ])
+ print(f"Fetching download URL from {download_url}")
+ response = httpx.get(download_url, follow_redirects=True)
+
+ if response.status_code != 200:
+ try:
+ print(response.json())
+ except json.JSONDecodeError:
+ pass
+
+ response.raise_for_status()
+
+ url = response.json()["url"]
+ print(f"Downloading build from {url}")
+ zipped_content = httpx.get(url, follow_redirects=True)
zipped_content.raise_for_status()
zip_file = Path("temp.zip")
@@ -115,8 +51,3 @@ def download_artifact(suite_id: int, url: str) -> None:
zip_file.unlink(missing_ok=True)
print("Wrote artifact content to target directory.")
-
-
-if __name__ == "__main__":
- print("Build started")
- download_artifact(*get_build_artifact())