arc: reading key (standalone page), top-to-bottom legend lighting, end-to-end flow blueprint
This commit is contained in:
Vendored
+113
@@ -0,0 +1,113 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1180" height="660" viewBox="0 0 1180 660" role="img" aria-label="End-to-end delivery flow in four lanes converging on one running workload. Change lane: a commit lands in the GitHub repository, ArgoCD renders and diffs it against the live cluster and syncs the difference - the cluster pulls, nothing pushes. Shape lane: the Helm chart plus a per-cluster values context passes the schema gate, which refuses to render if a required value is missing, and produces the manifests ArgoCD applies. Artefact lane: CI builds once, pushes the image to Azure Container Registry, the zot pull-through mirror caches it, and the node pulls by digest so the mirror catches the traffic. Secret lane: Azure Key Vault holds the values, the External Secrets operator syncs them into the cluster, and git only ever holds the reference. The workload that runs is the sum of all four: synced state, rendered shape, digest-pinned image, injected secret.">
|
||||
<defs>
|
||||
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#64748b"></path>
|
||||
</marker>
|
||||
</defs>
|
||||
<rect width="1180" height="660" fill="#ffffff"></rect>
|
||||
|
||||
<!-- title -->
|
||||
<text x="60" y="46" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="23" font-weight="700" fill="#0e1726">The delivery flow, end to end</text>
|
||||
<text x="61" y="70" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="13.5" fill="#64748b">four lanes, one workload - courses VI, VIII and VII, in the order the bytes travel</text>
|
||||
|
||||
<!-- convergence -->
|
||||
<rect x="950" y="110" width="170" height="470" rx="14" fill="#0c8fce" fill-opacity="0.06" stroke="#0c8fce" stroke-width="3"></rect>
|
||||
<text x="1035" y="146" text-anchor="middle" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="15" font-weight="700" fill="#0c8fce">THE WORKLOAD</text>
|
||||
<g font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="11" fill="#0e1726">
|
||||
<text x="970" y="186">synced state</text>
|
||||
<text x="970" y="208">(C-VI)</text>
|
||||
<text x="970" y="286">rendered shape</text>
|
||||
<text x="970" y="308">(C-VIII)</text>
|
||||
<text x="970" y="416">digest-pinned</text>
|
||||
<text x="970" y="438">image (C-VII)</text>
|
||||
<text x="970" y="516">injected secret</text>
|
||||
<text x="970" y="538">(C-VI)</text>
|
||||
</g>
|
||||
|
||||
<!-- CHANGE lane -->
|
||||
<text x="60" y="122" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="11" letter-spacing="2" fill="#0c8fce">CHANGE</text>
|
||||
<g font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">
|
||||
<rect x="60" y="136" width="150" height="48" rx="10" fill="none" stroke="#64748b" stroke-width="1.5"></rect>
|
||||
<text x="135" y="165" text-anchor="middle">a commit</text>
|
||||
<rect x="270" y="136" width="180" height="48" rx="10" fill="none" stroke="#64748b" stroke-width="1.5"></rect>
|
||||
<text x="360" y="165" text-anchor="middle">GitHub repo</text>
|
||||
<rect x="510" y="136" width="230" height="48" rx="10" fill="#0c8fce" fill-opacity="0.06" stroke="#0c8fce" stroke-width="2"></rect>
|
||||
<text x="625" y="165" text-anchor="middle" fill="#0c8fce">ArgoCD: render + diff + sync</text>
|
||||
</g>
|
||||
<g stroke="#64748b" stroke-width="1.5" marker-end="url(#arr)">
|
||||
<line x1="210" y1="160" x2="264" y2="160"></line>
|
||||
<line x1="740" y1="160" x2="944" y2="160"></line>
|
||||
</g>
|
||||
<line x1="450" y1="160" x2="504" y2="160" stroke="#64748b" stroke-width="1.5" stroke-dasharray="6 5" marker-end="url(#arr)"></line>
|
||||
<text x="477" y="150" text-anchor="middle" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="10" fill="#64748b">pull</text>
|
||||
<text x="510" y="206" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="11" fill="#64748b">the cluster pulls - no CI credential can touch it; drift is put back, rollback is git revert</text>
|
||||
|
||||
<!-- SHAPE lane -->
|
||||
<text x="60" y="252" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="11" letter-spacing="2" fill="#7c3aed">SHAPE</text>
|
||||
<g font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">
|
||||
<rect x="60" y="266" width="150" height="48" rx="10" fill="#7c3aed" fill-opacity="0.04" stroke="#7c3aed" stroke-width="1.5"></rect>
|
||||
<text x="135" y="295" text-anchor="middle">the chart</text>
|
||||
<rect x="230" y="266" width="170" height="48" rx="10" fill="#7c3aed" fill-opacity="0.04" stroke="#7c3aed" stroke-width="1.5"></rect>
|
||||
<text x="315" y="288" text-anchor="middle">values context</text>
|
||||
<text x="315" y="305" text-anchor="middle" font-size="10" fill="#64748b">one file per cluster</text>
|
||||
<rect x="460" y="266" width="130" height="48" rx="10" fill="#e8b44a" fill-opacity="0.08" stroke="#e8b44a" stroke-width="2"></rect>
|
||||
<text x="525" y="288" text-anchor="middle" fill="#8a6414">schema gate</text>
|
||||
<text x="525" y="305" text-anchor="middle" font-size="10" fill="#8a6414">required, or refuse</text>
|
||||
<rect x="650" y="266" width="180" height="48" rx="10" fill="none" stroke="#64748b" stroke-width="1.5"></rect>
|
||||
<text x="740" y="295" text-anchor="middle">rendered manifests</text>
|
||||
</g>
|
||||
<g stroke="#64748b" stroke-width="1.5" marker-end="url(#arr)">
|
||||
<line x1="210" y1="290" x2="224" y2="290"></line>
|
||||
<line x1="400" y1="290" x2="454" y2="290"></line>
|
||||
<line x1="590" y1="290" x2="644" y2="290"></line>
|
||||
<path d="M 740 266 L 740 236 L 660 236 L 660 190" fill="none"></path>
|
||||
</g>
|
||||
<text x="756" y="242" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="10" fill="#64748b">into the sync</text>
|
||||
|
||||
<!-- ARTEFACT lane -->
|
||||
<text x="60" y="392" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="11" letter-spacing="2" fill="#c026d3">ARTEFACT</text>
|
||||
<g font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">
|
||||
<rect x="60" y="406" width="150" height="48" rx="10" fill="none" stroke="#64748b" stroke-width="1.5"></rect>
|
||||
<text x="135" y="428" text-anchor="middle">CI builds</text>
|
||||
<text x="135" y="445" text-anchor="middle" font-size="10" fill="#64748b">once, only once</text>
|
||||
<rect x="270" y="406" width="180" height="48" rx="10" fill="#c026d3" fill-opacity="0.04" stroke="#c026d3" stroke-width="1.5"></rect>
|
||||
<text x="360" y="428" text-anchor="middle">ACR upstream</text>
|
||||
<text x="360" y="445" text-anchor="middle" font-size="10" fill="#64748b">tag@sha256 minted</text>
|
||||
<rect x="510" y="406" width="180" height="48" rx="10" fill="#c026d3" fill-opacity="0.04" stroke="#c026d3" stroke-width="1.5"></rect>
|
||||
<text x="600" y="428" text-anchor="middle">zot mirror</text>
|
||||
<text x="600" y="445" text-anchor="middle" font-size="10" fill="#64748b">the fleet pulls once</text>
|
||||
<rect x="750" y="406" width="150" height="48" rx="10" fill="none" stroke="#64748b" stroke-width="1.5"></rect>
|
||||
<text x="825" y="428" text-anchor="middle">node pulls</text>
|
||||
<text x="825" y="445" text-anchor="middle" font-size="10" fill="#64748b">by digest</text>
|
||||
</g>
|
||||
<g stroke="#64748b" stroke-width="1.5" marker-end="url(#arr)">
|
||||
<line x1="210" y1="430" x2="264" y2="430"></line>
|
||||
<line x1="450" y1="430" x2="504" y2="430"></line>
|
||||
<line x1="690" y1="430" x2="744" y2="430"></line>
|
||||
<line x1="900" y1="430" x2="944" y2="430"></line>
|
||||
</g>
|
||||
<text x="60" y="480" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="11" fill="#64748b">promotion is a copy of the same digest - if the digest changed, it is a new candidate, not a promotion</text>
|
||||
|
||||
<!-- SECRET lane -->
|
||||
<text x="60" y="522" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="11" letter-spacing="2" fill="#8a6414">SECRET</text>
|
||||
<g font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">
|
||||
<rect x="60" y="536" width="180" height="48" rx="10" fill="#e8b44a" fill-opacity="0.08" stroke="#e8b44a" stroke-width="1.5"></rect>
|
||||
<text x="150" y="558" text-anchor="middle" fill="#8a6414">Azure Key Vault</text>
|
||||
<text x="150" y="575" text-anchor="middle" font-size="10" fill="#8a6414">holds the values</text>
|
||||
<rect x="300" y="536" width="180" height="48" rx="10" fill="none" stroke="#64748b" stroke-width="1.5"></rect>
|
||||
<text x="390" y="558" text-anchor="middle">ESO operator</text>
|
||||
<text x="390" y="575" text-anchor="middle" font-size="10" fill="#64748b">exchanges + keeps synced</text>
|
||||
<rect x="540" y="536" width="180" height="48" rx="10" fill="none" stroke="#64748b" stroke-width="1.5"></rect>
|
||||
<text x="630" y="558" text-anchor="middle">Secret, in-cluster</text>
|
||||
<text x="630" y="575" text-anchor="middle" font-size="10" fill="#64748b">never in git</text>
|
||||
</g>
|
||||
<g stroke="#64748b" stroke-width="1.5" marker-end="url(#arr)">
|
||||
<line x1="240" y1="560" x2="294" y2="560"></line>
|
||||
<line x1="480" y1="560" x2="534" y2="560"></line>
|
||||
<line x1="720" y1="560" x2="944" y2="560"></line>
|
||||
</g>
|
||||
<text x="760" y="550" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="10" fill="#64748b">git holds only the reference</text>
|
||||
|
||||
<!-- footer -->
|
||||
<text x="590" y="636" text-anchor="middle" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="12.5" font-weight="700" fill="#0e1726">this page shipped through this exact flow - the delivery arc is deployed by a delivery arc</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
@@ -13,7 +13,8 @@ cd -- "$here"
|
||||
for f in pilot/arc.tpl.html pilot/manifest-gitops.json pilot/manifest-supply.json \
|
||||
pilot/manifest-helm.json gsap.min.js st.min.js \
|
||||
assets/dist/course-VI-gitops.webp assets/dist/course-VII-supply-chain.webp \
|
||||
assets/dist/course-VIII-helm-press.webp assets/dist/appendix-dependency-ledger.webp; do
|
||||
assets/dist/course-VIII-helm-press.webp assets/dist/appendix-dependency-ledger.webp \
|
||||
assets/dist/delivery-flow.svg; do
|
||||
[[ -f "$f" ]] || { printf 'missing source: %s\n' "$f" >&2; exit 1; }
|
||||
done
|
||||
|
||||
|
||||
+55
-9
@@ -6,6 +6,15 @@
|
||||
<p class="scrollcue" aria-hidden="true">scroll<span></span></p>
|
||||
</header>
|
||||
|
||||
<aside class="key" aria-label="reading key">
|
||||
<p class="kt">Reading key · this page stands alone - anything it leans on is listed here</p>
|
||||
<ul>
|
||||
<li><b>C-I</b><span>Docker: an image is a stack of frozen diffs. Referenced by Course VII.</span><i>course lands here soon</i></li>
|
||||
<li><b>C-II</b><span>Kubernetes: a cluster is a promise - the reconciliation loop. Referenced by Courses VI and VIII.</span><i>course lands here soon</i></li>
|
||||
<li><b>BLOG</b><span>Consistency by construction beats consistency by discipline - Course VIII's contexts move, lived on a real fleet.</span><a href="https://www.bztmon.com/blog/one-value-many-enforcers/">read it on bztmon.com</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<!-- ============ COURSE VI ============ -->
|
||||
<section class="course" id="c6" data-scene="gitops" aria-labelledby="c6h">
|
||||
<header class="chead">
|
||||
@@ -30,7 +39,7 @@
|
||||
</div>
|
||||
<div class="prose">
|
||||
<h3>The loop you already know, one level up</h3>
|
||||
<p>Course II taught the reconciliation loop: desired versus actual, fix the difference, repeat.
|
||||
<p>C-II taught the reconciliation loop: desired versus actual, fix the difference, repeat.
|
||||
ArgoCD is the same habit applied to <b>delivery</b>. An Application names a repo, a path and a
|
||||
revision - watch this branch of this repository - and the controller renders what it finds
|
||||
there, compares it against the live cluster, and syncs the difference. The deploy button is a
|
||||
@@ -44,7 +53,7 @@
|
||||
it back, and what leaves git leaves the cluster. Rollback is <span class="mono">git revert</span>,
|
||||
which is why commit hygiene is an operational skill.</p>
|
||||
<p class="fieldnote"><b>Field note.</b> Fighting the reconciler over SSH is arm-wrestling a
|
||||
machine that does not get tired - Course II's warning, now with a face. The fix is always
|
||||
machine that does not get tired - C-II's warning, now with a face. The fix is always
|
||||
upstream, in git.</p>
|
||||
<h3>The one thing git never holds</h3>
|
||||
<p>Git holds everything except secrets - a secret in git is published, forever, to everyone who
|
||||
@@ -57,7 +66,7 @@
|
||||
<p class="closeline">Delivery stops being an event and becomes a property: the cluster is always
|
||||
converging on what the repository says. "Who deployed this?" becomes "who merged this?" - and
|
||||
that question always has an answer.</p>
|
||||
<p class="reads"><b>Pre-reads:</b> Course II ·
|
||||
<p class="reads"><b>Pre-reads:</b> C-II ·
|
||||
<a href="https://kubernetes.io/docs/concepts/">Kubernetes concepts</a> ·
|
||||
<a href="https://docs.github.com/en/get-started">git + pull requests</a>
|
||||
 <b>Further:</b> <a href="https://argo-cd.readthedocs.io/">Argo CD</a> ·
|
||||
@@ -117,7 +126,7 @@
|
||||
<p class="closeline">Names that can move are convenient exactly until they move. Address content
|
||||
by what it is, and the supply chain stops being a chain of trust and becomes a chain of
|
||||
arithmetic.</p>
|
||||
<p class="reads"><b>Pre-reads:</b> Course I ·
|
||||
<p class="reads"><b>Pre-reads:</b> C-I ·
|
||||
<a href="https://kubernetes.io/docs/concepts/containers/images/">Kubernetes images</a>
|
||||
 <b>Further:</b> <a href="https://zotregistry.dev/">zot</a> ·
|
||||
<a href="https://learn.microsoft.com/azure/container-registry/">Azure Container Registry</a> ·
|
||||
@@ -164,7 +173,7 @@
|
||||
one values file: names, addresses, sizes, flags. The context is deliberately values-only; the
|
||||
moment it carries its own manifests there are two owners for one object, and they will
|
||||
disagree. One value can feed many rendered artefacts - an address appearing in the app config,
|
||||
the network attachment and two policies renders from one field, so the copies cannot diverge.</p>
|
||||
the network attachment and two policies renders from one field, so the copies cannot diverge - the lived version is <a href="https://www.bztmon.com/blog/one-value-many-enforcers/">BLOG in the key above</a>.</p>
|
||||
<p class="sayit">The chart owns the shape. The context owns the numbers.</p>
|
||||
<h3>Make the template refuse</h3>
|
||||
<p>A template that renders whatever it is given just moves the failure downstream. The grown-up
|
||||
@@ -176,7 +185,7 @@
|
||||
<p class="closeline">Fleet consistency is not a discipline problem, it is a construction
|
||||
problem. Divergence stops being something you police and becomes something the tooling cannot
|
||||
express.</p>
|
||||
<p class="reads"><b>Pre-reads:</b> Course II ·
|
||||
<p class="reads"><b>Pre-reads:</b> C-II ·
|
||||
<a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/">Kubernetes objects</a>
|
||||
 <b>Further:</b> <a href="https://helm.sh/docs/">Helm docs</a> ·
|
||||
<a href="https://helm.sh/docs/chart_template_guide/">chart template guide</a> ·
|
||||
@@ -245,6 +254,27 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="course" id="flow" aria-labelledby="flowh">
|
||||
<header class="chead">
|
||||
<p class="eyebrow">The whole arc · end to end</p>
|
||||
<h2 id="flowh" class="thesis">One flow, <em>no gaps.</em></h2>
|
||||
<p class="lede">Every course above is one stretch of the same journey. Here is the full run,
|
||||
drawn in the house blueprint style: the change lane, the shape lane, the artefact lane and
|
||||
the secret lane, all converging on one running workload.</p>
|
||||
</header>
|
||||
<figure class="blueprint">
|
||||
<img src="__DIAG_FLOW__"
|
||||
alt="End-to-end delivery flow. Change lane: a commit lands in the GitHub repository, ArgoCD
|
||||
renders and diffs it, and syncs the cluster - the cluster pulls, nothing pushes.
|
||||
Shape lane: the Helm chart plus a per-cluster values context passes the schema gate
|
||||
and renders the manifests ArgoCD applies. Artefact lane: CI builds once, pushes to
|
||||
Azure Container Registry, the zot mirror caches it, and the node pulls by digest.
|
||||
Secret lane: Azure Key Vault holds the values, the External Secrets operator syncs
|
||||
them in - git only ever holds the reference. All four lanes converge on the running
|
||||
workload.">
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<footer class="outro">
|
||||
<p>The Exploded Cluster · the delivery arc · every scene is one generated hero,
|
||||
sliced and scrubbed - no diagrams were harmed.</p>
|
||||
@@ -275,6 +305,22 @@ b{color:var(--ink)} .mono{font-family:var(--mono);font-size:.9em;color:var(--cya
|
||||
color:var(--dim);margin-top:4.5rem;display:flex;flex-direction:column;align-items:center;gap:.7rem}
|
||||
.scrollcue span{display:block;width:1px;height:46px;background:linear-gradient(var(--cyan),transparent)}
|
||||
|
||||
.key{max-width:760px;margin:0 auto;padding:0 24px 4vh}
|
||||
.key .kt{font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
|
||||
color:var(--dim);text-align:center;margin:0 0 1rem}
|
||||
.key ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
|
||||
.key li{display:grid;grid-template-columns:52px 1fr auto;gap:14px;align-items:baseline;
|
||||
border:1px solid var(--line);border-radius:8px;padding:10px 16px;background:#0a1020}
|
||||
.key b{font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;color:var(--cyan)}
|
||||
.key span{font-size:.82rem;line-height:1.5;color:var(--dim)}
|
||||
.key i{font-family:var(--mono);font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;
|
||||
color:var(--amber);font-style:normal;white-space:nowrap}
|
||||
.key a{font-family:var(--mono);font-size:.66rem;letter-spacing:.06em;white-space:nowrap}
|
||||
@media (max-width:700px){.key li{grid-template-columns:44px 1fr}.key i,.key a{grid-column:2}}
|
||||
|
||||
.blueprint{max-width:1220px;margin:2vh auto 4vh;padding:0 24px}
|
||||
.blueprint img{width:100%;height:auto;display:block;border-radius:12px}
|
||||
|
||||
.course{position:relative;padding-top:10vh}
|
||||
.chead{max-width:64ch;margin:0 auto;padding:4vh 24px 2vh;text-align:center}
|
||||
.chead .thesis{font-size:clamp(1.6rem,4vw,2.6rem)}
|
||||
@@ -370,16 +416,16 @@ body:not(.fx) .bench{display:none}
|
||||
return d;
|
||||
});
|
||||
u.flat.style.visibility = "hidden";
|
||||
const dists = u.man.parts.map(p => Math.hypot(p.dx, p.dy));
|
||||
const maxD = Math.max(...dists, 1e-6);
|
||||
const lis = [...u.legend.children];
|
||||
const n = lis.length;
|
||||
u.apply = t => {
|
||||
u.man.parts.forEach((p, i) => {
|
||||
u.slabs[i].style.transform =
|
||||
"translate3d(" + (p.dx * (1 - t)).toFixed(3) + "%," + (p.dy * (1 - t)).toFixed(3) + "%,0)";
|
||||
});
|
||||
u.scene.style.transform = "scale(" + (0.95 + 0.05 * t).toFixed(4) + ")";
|
||||
lis.forEach((li, i) => li.classList.toggle("lit", t >= 0.82 * (dists[i] / maxD)));
|
||||
// the side list lights in reading order, top to bottom, as the scrub advances
|
||||
lis.forEach((li, i) => li.classList.toggle("lit", t >= 0.9 * ((i + 0.5) / n)));
|
||||
};
|
||||
// bench: hand scrub + HUD (pilot instrument - strip for the site ship)
|
||||
const bench = u.sec.querySelector(".bench");
|
||||
|
||||
@@ -31,7 +31,8 @@ const heroes = {
|
||||
__HERO_APPENDIX__: "appendix-dependency-ledger.webp",
|
||||
};
|
||||
for (const [ph, file] of Object.entries(heroes)) body = body.replace(ph, "/assets/" + file);
|
||||
if (body.includes("__HERO_") || app.includes("__MAN_")) throw new Error("unfilled placeholder");
|
||||
body = body.replace("__DIAG_FLOW__", "/assets/delivery-flow.svg");
|
||||
if (body.includes("__HERO_") || body.includes("__DIAG_") || app.includes("__MAN_")) throw new Error("unfilled placeholder");
|
||||
|
||||
const favicon = "data:image/svg+xml," + encodeURIComponent(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" fill="#070b14"/><rect x="6" y="4" width="14" height="7" rx="1.5" fill="#3fbaf5"/><rect x="11" y="13" width="14" height="7" rx="1.5" fill="#7dd0f9"/><rect x="6" y="22" width="14" height="7" rx="1.5" fill="#e879f9"/></svg>`);
|
||||
@@ -61,6 +62,7 @@ writeFileSync(join(DIST, "arc.js"), app);
|
||||
copyFileSync(join(ROOT, "gsap.min.js"), join(DIST, "gsap.min.js"));
|
||||
copyFileSync(join(ROOT, "st.min.js"), join(DIST, "st.min.js"));
|
||||
for (const f of Object.values(heroes)) copyFileSync(join(ROOT, "assets/dist", f), join(DIST, "assets", f));
|
||||
copyFileSync(join(ROOT, "assets/dist/delivery-flow.svg"), join(DIST, "assets/delivery-flow.svg"));
|
||||
|
||||
// CSP gate: no inline <script> may survive into the served HTML
|
||||
const inline = (html.match(/<script(?![^>]*src=)[^>]*>/gi) || []).length;
|
||||
|
||||
@@ -22,9 +22,10 @@ out = (ROOT / "pilot/arc.tpl.html").read_text() \
|
||||
.replace("__HERO_GITOPS__", b64("course-VI-gitops.webp")) \
|
||||
.replace("__HERO_SUPPLY__", b64("course-VII-supply-chain.webp")) \
|
||||
.replace("__HERO_HELM__", b64("course-VIII-helm-press.webp")) \
|
||||
.replace("__HERO_APPENDIX__", b64("appendix-dependency-ledger.webp"))
|
||||
.replace("__HERO_APPENDIX__", b64("appendix-dependency-ledger.webp")) \
|
||||
.replace("__DIAG_FLOW__", "data:image/svg+xml;base64," + base64.b64encode((ROOT / "assets/dist/delivery-flow.svg").read_bytes()).decode())
|
||||
|
||||
assert "__MAN_" not in out and "__HERO_" not in out, "unfilled placeholder"
|
||||
assert "__MAN_" not in out and "__HERO_" not in out and "__DIAG_" not in out, "unfilled placeholder"
|
||||
|
||||
out = (f"<script>{(ROOT / 'gsap.min.js').read_text()}</script>\n"
|
||||
f"<script>{(ROOT / 'st.min.js').read_text()}</script>\n" + out)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{
|
||||
"name": "image",
|
||||
"title": "The image",
|
||||
"blurb": "Course I's layers, shipped as one unit - the thing whose name we must say precisely.",
|
||||
"blurb": "C-I's layers, shipped as one unit - the thing whose name we must say precisely.",
|
||||
"z": 0,
|
||||
"points": [
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user