Skip to content

Commit 849cfb3

Browse files
Merge pull request #1 from pip-install-python/network-standard-0.2.1
Network standard 0.2.1
2 parents 417535a + b2ef5f8 commit 849cfb3

49 files changed

Lines changed: 3444 additions & 102 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
-53 KB
Binary file not shown.

.flake8

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[flake8]
2+
# Copied from dash-documentation-boilerplate (the network template).
3+
#
4+
# Line length is not policed: this repo's comments carry a lot of explanation
5+
# and reflowing them to 79 columns would make them harder to read, not easier.
6+
max-line-length = 120
7+
extend-ignore = E203, W503, E501
8+
exclude =
9+
.git,
10+
.venv,
11+
__pycache__,
12+
node_modules,
13+
vendor,
14+
dist,
15+
build,
16+
.idea,
17+
dash_leaflet2,
18+
docs/*/,
19+
per-file-ignores =
20+
# run.py imports Dash and the lib modules after `load_dotenv()`, which has
21+
# to run first — the CLERK_* keys and CROSS_APP_WEBHOOK_SECRET must be in
22+
# the environment before Dash construction imports anything that reads
23+
# them. The appshell import at the bottom needs the page registry to be
24+
# populated, so it cannot move to the top either.
25+
run.py: E402
26+
# usage.py is the compiled-package harness, same import-order constraint.
27+
usage.py: E402

.github/dependabot.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Version drift is the network's chronic disease — satellites were still
2+
# running a 2.0-era artifact the day 2.3.4 shipped, and nothing about a stale
3+
# host looks broken from the outside. This is the standing fix.
4+
#
5+
# Copied from dash-documentation-boilerplate. The `dash-network` group is the
6+
# point: a package release lands as ONE reviewable pull request per repo
7+
# instead of five, which is the difference between a rollout and a chore.
8+
#
9+
# npm is here and not in the template because this repo also builds the
10+
# dash-leaflet2 component bundle from src/ts.
11+
version: 2
12+
updates:
13+
- package-ecosystem: pip
14+
directory: "/"
15+
schedule:
16+
interval: weekly
17+
day: monday
18+
open-pull-requests-limit: 5
19+
groups:
20+
dash-network:
21+
patterns:
22+
- "dash*"
23+
- "plotly*"
24+
- "markdown2dash"
25+
26+
- package-ecosystem: npm
27+
directory: "/"
28+
schedule:
29+
interval: weekly
30+
day: monday
31+
open-pull-requests-limit: 5
32+
groups:
33+
build-toolchain:
34+
patterns:
35+
- "*"
36+
37+
- package-ecosystem: github-actions
38+
directory: "/"
39+
schedule:
40+
interval: monthly
41+
groups:
42+
actions:
43+
patterns:
44+
- "*"
45+
46+
- package-ecosystem: docker
47+
directory: "/"
48+
schedule:
49+
interval: monthly

.github/workflows/cd.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: CD
2+
3+
# Deploys leaflet.2plot.dev, then checks the live site.
4+
#
5+
# The deploy step POSTs to a Render deploy hook held in the
6+
# RENDER_DEPLOY_HOOK_URL secret. Without that secret the step is skipped and
7+
# the workflow goes straight to verification — which is the situation this repo
8+
# is in today: render.yaml sets `autoDeploy: true`, so Render is already
9+
# building from GitHub on its own. Adding the secret later moves the trigger
10+
# here without changing anything else.
11+
on:
12+
push:
13+
branches: [main]
14+
workflow_dispatch:
15+
inputs:
16+
target_url:
17+
description: Site to verify (skips the deploy when set to another host)
18+
required: false
19+
type: string
20+
21+
permissions:
22+
contents: read
23+
24+
concurrency:
25+
group: cd-production
26+
cancel-in-progress: false
27+
28+
env:
29+
PIP_DISABLE_PIP_VERSION_CHECK: "1"
30+
SITE_URL: ${{ inputs.target_url || 'https://leaflet.2plot.dev' }}
31+
32+
jobs:
33+
test:
34+
name: ci
35+
uses: ./.github/workflows/ci.yml
36+
37+
deploy:
38+
name: deploy to render
39+
needs: [test]
40+
runs-on: ubuntu-latest
41+
# Long enough for the wait loop below (a 120s settle plus up to 40 × 15s)
42+
# and no longer. Without it the job inherits GitHub's six-hour default,
43+
# which is how a platform that never comes back healthy holds the
44+
# `cd-production` concurrency group all day.
45+
timeout-minutes: 20
46+
environment:
47+
name: production
48+
url: https://leaflet.2plot.dev
49+
outputs:
50+
deployed: ${{ steps.hook.outputs.deployed }}
51+
steps:
52+
- name: Trigger the Render deploy hook
53+
id: hook
54+
env:
55+
HOOK: ${{ secrets.RENDER_DEPLOY_HOOK_URL }}
56+
run: |
57+
if [ -z "$HOOK" ]; then
58+
echo "::notice::RENDER_DEPLOY_HOOK_URL is not set. Skipping the deploy trigger and verifying whatever is currently live."
59+
echo "deployed=false" >> "$GITHUB_OUTPUT"
60+
exit 0
61+
fi
62+
curl -fsS -X POST "$HOOK" > /dev/null
63+
echo "deployed=true" >> "$GITHUB_OUTPUT"
64+
65+
- name: Wait for the new build to serve traffic
66+
if: steps.hook.outputs.deployed == 'true'
67+
run: |
68+
# Render swaps instances rather than restarting in place, so the old
69+
# build answers /healthz throughout. Waiting for a 200 proves
70+
# nothing; give the build time, then require SUSTAINED health.
71+
#
72+
# This site is on Render's free tier (render.yaml), which also sleeps
73+
# after ~15 minutes idle — so a single 200 can just as easily be a
74+
# cold start as a finished deploy.
75+
sleep 120
76+
ok=0
77+
for _ in $(seq 1 40); do
78+
if curl -fsS "$SITE_URL/healthz" > /dev/null; then
79+
ok=$((ok + 1))
80+
[ "$ok" -ge 5 ] && break
81+
else
82+
ok=0
83+
fi
84+
sleep 15
85+
done
86+
if [ "$ok" -lt 5 ]; then
87+
echo "::error::$SITE_URL never became reliably healthy"
88+
exit 1
89+
fi
90+
91+
verify:
92+
name: verify the live site
93+
needs: [deploy]
94+
if: always() && needs.deploy.result != 'cancelled'
95+
runs-on: ubuntu-latest
96+
timeout-minutes: 15
97+
steps:
98+
- uses: actions/checkout@v4
99+
- uses: actions/setup-python@v5
100+
with:
101+
python-version: "3.12"
102+
103+
# The network battery first: it is the same script, with the same check
104+
# names, that CI ran against the container this deploy shipped. A name
105+
# that passed in CI and fails here isolates the fault to the deploy.
106+
- name: Network smoke battery
107+
run: python scripts/network_smoke.py --base-url "$SITE_URL"
108+
109+
# Then the satellite-specific checks the battery does not make: every
110+
# canonical, every crawler body, and every peer llms.txt in the
111+
# directory actually resolving. Peer failures warn; this host's fail.
112+
- name: Smoke-test the deployment
113+
run: python scripts/smoke_live.py "$SITE_URL"
114+
115+
- name: Report
116+
if: failure()
117+
run: |
118+
echo "::error::Live verification failed for $SITE_URL. Every failure these check for is silent in production: a site identity that fell back to a framework default, a stale dash-improve-my-llms artifact, a canonical on the wrong host, a page serving the JavaScript stub, a missing network directory, and dead peer llms.txt links."

0 commit comments

Comments
 (0)