WEB / WEB-21.01
From source to deployment
Read build bytes, selected checks, and release/environment decisions through distinct evidence.
1. Core · Mechanism
Read every scenario without motion
Local build
- Input identity
The public-note.json and theme.css source inputs are ready. The local builder has not produced index.html/site.css, and the verifier has not checked those outputs.
- Source inputs
- Fixed public inputs
- Local builder
- Builder not run
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Read inputs
The builder reads only own temporary public-note.json and theme.css inputs; no unrelated user files are involved.
- Source inputs
- Fixed public inputs
- Local builder
- Required inputs read
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Render / copy
The own build renders the title into HTML and copies CSS bytes; no JavaScript module bundler runs.
- Source inputs
- Fixed public inputs
- Local builder
- HTML / CSS produced
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Artifact identity
Fixed entry order and timestamps produce a static archive; the digest identifies exact bytes rather than approval.
- Source inputs
- Fixed public inputs
- Local builder
- Archive / digest ready
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Independent read
The verifier independently parses the produced HTML title and reads ZIP entries and CSS bytes.
- Source inputs
- Fixed public inputs
- Local builder
- Archive / digest ready
- Independent verifier
- Tea title / entries read
- Local candidate registry
- baseline-a only
- Gate pass
Selected local assertions pass; this verification establishes neither publication, environment parity, nor runtime health.
- Source inputs
- Fixed public inputs
- Local builder
- Archive / digest ready
- Independent verifier
- Selected checks passed
- Local candidate registry
- baseline-a only
- Local record
The local candidate registry records the tested digest; no deployment, route activation, or push occurs.
- Source inputs
- Fixed public inputs
- Local builder
- Archive / digest ready
- Independent verifier
- Selected checks passed
- Local candidate registry
- candidate-a local only
Gate failed
- Input fixed
Source still contains Tea note; this branch gives the verifier an expected title of Coffee note. The builder has not produced output or decided this mismatch yet.
- Source inputs
- Fixed public inputs
- Local builder
- Builder not run
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Build succeeds
The own builder produces valid Tea HTML; build success does not establish the independently expected content.
- Source inputs
- Fixed public inputs
- Local builder
- Tea HTML produced
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Read actual
The independent parser reads actual Tea note; expected Coffee note remains a separate test expectation.
- Source inputs
- Fixed public inputs
- Local builder
- Tea HTML produced
- Independent verifier
- Actual Tea title read
- Local candidate registry
- baseline-a only
- Gate rejects
The content assertion mismatch makes verification fail; the candidate is not considered ready for promotion.
- Source inputs
- Fixed public inputs
- Local builder
- Tea HTML produced
- Independent verifier
- Expected mismatch
- Local candidate registry
- baseline-a only
- Record preserved
The local baseline remains unchanged; the failed check is not marked as production or an approved artifact.
- Source inputs
- Fixed public inputs
- Local builder
- Tea HTML produced
- Independent verifier
- Expected mismatch
- Local candidate registry
- baseline-a unchanged
Missing input
- Missing input
This branch lacks the required theme.css source input. A missing input differs from a content check failing on an existing output.
- Source inputs
- theme.css missing
- Local builder
- Builder not run
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Check set
The builder checks the declared input set; no candidate is reused as if an old archive were a new build.
- Source inputs
- theme.css missing
- Local builder
- Input set checked
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Build stops
With a required input missing, the build stops and candidateCreated remains false; partial output is not ready.
- Source inputs
- theme.css missing
- Local builder
- Build stops: missing
- Independent verifier
- Verifier not run
- Local candidate registry
- baseline-a only
- Gate not run
No candidate exists, so the verifier does not run; not-run cannot be interpreted as passed.
- Source inputs
- theme.css missing
- Local builder
- Build stops: missing
- Independent verifier
- Verification not run
- Local candidate registry
- baseline-a only
- No new candidate
The local registry preserves the baseline; no digest or deployment status is invented for nonexistent output.
- Source inputs
- theme.css missing
- Local builder
- Build stops: missing
- Independent verifier
- Verification not run
- Local candidate registry
- baseline-a unchanged
Runtime config
- Bytes fixed
The same static-package digest is retained; public runtime config is a separate input from package bytes. The config decoder has not evaluated READ_ONLY yet.
- Source inputs
- Static package fixed
- Local builder
- Public config supplied
- Independent verifier
- Parser not run
- Local candidate registry
- Deployment absent
- Text input
Supplied READ_ONLY=false is a string; the native check reads neither process environment nor a .env file.
- Source inputs
- Static package fixed
- Local builder
- Public config supplied
- Independent verifier
- false text observed
- Local candidate registry
- Deployment absent
- Typed gate
The selected parser maps exact false text to boolean false rather than using generic truthiness.
- Source inputs
- Static package fixed
- Local builder
- Public config supplied
- Independent verifier
- Typed false accepted
- Local candidate registry
- Deployment absent
- Alternate config selected
The local builder selects alternate public true text as a separate input; the verifier’s previous typed-false result stays fixed and static package bytes remain identical.
- Source inputs
- Static package fixed
- Local builder
- Alternate true supplied
- Independent verifier
- Typed false accepted
- Local candidate registry
- Deployment absent
- Alternate typed validation
The independent verifier parses selected true text into typed true; the builder’s selected input and static package bytes do not change in this local step.
- Source inputs
- Static package fixed
- Local builder
- Alternate true supplied
- Independent verifier
- Typed true accepted
- Local candidate registry
- Deployment absent
- Scope separated
Local config-parsing scope is recorded; no server startup, release approval, or deployment occurs.
- Source inputs
- Static package fixed
- Local builder
- Alternate true supplied
- Independent verifier
- Typed true accepted
- Local candidate registry
- Local only / no release
ACTORS · STATE · DATA FLOW
Source, build output, and environment carry different evidence
Development, test, staging, and production names are not quality results. Development produces changes, tests check selected behavior, staging can examine a release candidate with more representative configuration and dependencies, and production serves users. Identical names do not guarantee identical isolation or data policies across projects. Passing a staging check does not establish matching production secrets, network rules, load, or migration state.
Source identity differs from the byte identity of build output. A build processes declared inputs using a toolchain and options: HTML rendering, TypeScript transforms, CSS processing, copying, or packaging. A source change need not alter every output, and the same source can yield different output under another toolchain or configuration. Record source revision, dependency/tool versions, options, and output digests together. SHA-256 identifies bytes; it is not by itself a trusted-builder or authorized-release signature.
The own fixture builds index.html and site.css from public-note.json and theme.css. Fixed ZIP entry order and timestamps yield the same byte digest on repetition. Native checks actually write temporary files, read the title through an independent HTML parser, and inspect archive entries and CSS bytes separately. This is bounded deterministic-build evidence, not ecosystem-wide reproducibility, a repository build, or deployment.
At which stage do bundling, CI/CD, and configuration act?
Bundling processes an imported dependency graph around an entry point and connects it to outputs. It differs from concatenation and ZIP packaging. Minification affects representation size, while bundling changes code/dependency organization. esbuild Bundle is a named example of recursively inlining imports; external or unanalyzable imports can remain runtime dependencies. The native ZIP here packages static files and does not execute esbuild.
CI combines frequent integration into a shared repository with automated build/test feedback for each integration. A nightly build or automation job alone does not establish that integration practice. CD terminology needs context: continuous delivery can prepare a releasable candidate while retaining a separate release decision; continuous deployment can automatically promote changes that pass policy. GitHub workflow jobs, runners, and steps provide a named example. An artifact record or green job alone does not establish the scope of a release gate. All stages here remain in a local candidate ledger with no deployment.
Environment configuration may be embedded in browser bytes at build time or read by a server at runtime. Public browser config is not secret storage. Node dotenv values are strings, so the text false must not be interpreted through general truthiness as a boolean. The fixture accepts only true/false for supplied READ_ONLY text and reads no process environment or .env file. Different runtime configurations can accompany the same static artifact digest; hash equality alone does not establish equal behavior.
2. Red · Trust & Impact
Read every scenario without motion
Content gate
- Public input set
public-note.json contains Tea note and theme.css the supplied style bytes. Output consists only of index.html and site.css; source and artifact are distinct.
- Candidate ledger
- Two inputs / two output entries
- Verification gate
- Not yet evaluated
- Local promotion outcome
- Not yet evaluated
- Content-check difference
gateFailed expects Coffee note but observes Tea note. Producing HTML does not mean the independent content expectation passed.
- Candidate ledger
- Two inputs / two output entries
- Verification gate
- Coffee expected / Tea actual / verified false
- Local promotion outcome
- Not yet evaluated
- Retain the baseline
A failed verifier leaves promoted false and retains baseline-a. The local alias is not a production route and claims no deployment or rollback execution.
- Candidate ledger
- Two inputs / two output entries
- Verification gate
- Coffee expected / Tea actual / verified false
- Local promotion outcome
- Failed candidate / baseline-a retained
- Question answered by a digest
Normal output digests bind exact byte identity. If manifest and output both change without control, a digest does not establish trusted source or release authority.
- Candidate ledger
- Byte identity ≠ trusted provenance
- Verification gate
- Coffee expected / Tea actual / verified false
- Local promotion outcome
- Failed candidate / baseline-a retained
- Entry allowlist
The archive allowlist contains index.html/site.css only. Adding source notes, expectations or secrets can violate packaging even if a hash matches.
- Candidate ledger
- Byte identity ≠ trusted provenance
- Verification gate
- Only index.html / site.css allowed
- Local promotion outcome
- Failed candidate / baseline-a retained
- Separate gate result
Normal verified true is recorded as candidate-a, but deployed remains false. Content checks and exact artifact binding explain the local result without deriving publication authority.
- Candidate ledger
- Byte identity ≠ trusted provenance
- Verification gate
- Only index.html / site.css allowed
- Local promotion outcome
- Verified local candidate / deployed false
Input and config
- Missing required input
When required theme.css is absent, candidateCreated and verificationRun are false. Seeing an old filename does not establish a newly produced candidate.
- Candidate ledger
- theme.css missing / no new candidate
- Verification gate
- Not yet evaluated
- Local promotion outcome
- Not yet evaluated
- Do not default to success
If verification did not run, a pass cannot be recorded. Missing input, compile failure and content mismatch are different gates; one failure label can lose information.
- Candidate ledger
- theme.css missing / no new candidate
- Verification gate
- Not run ≠ check passed
- Local promotion outcome
- Not yet evaluated
- Retain candidate absence
This branch has no archive candidate. Counting baseline bytes as new output hides missing-input coverage; digest and existence must be retained together.
- Candidate ledger
- theme.css missing / no new candidate
- Verification gate
- Not run ≠ check passed
- Local promotion outcome
- No candidate / baseline not a new build
- Boolean-string distinction
READ_ONLY string false parses false, while alternateText true parses true. Nonempty-string truthiness cannot replace this public configuration parser.
- Candidate ledger
- String false → false / true → true
- Verification gate
- Not run ≠ check passed
- Local promotion outcome
- No candidate / baseline not a new build
- Same package, different behavior
Behavior may change while sameStaticPackage remains true. Config is public and processEnvironmentRead false; this is not server-secret, vault or actual startup evidence.
- Candidate ledger
- String false → false / true → true
- Verification gate
- Static identity same / config semantics differ
- Local promotion outcome
- No candidate / baseline not a new build
- Retain three boundaries
Input existence, independent verification and typed configuration remain separate. Static-file packaging is not a JS module bundler; esbuildExecuted false retains that distinction.
- Candidate ledger
- String false → false / true → true
- Verification gate
- Static identity same / config semantics differ
- Local promotion outcome
- Inputs / verification / config distinct
ASSUMPTION · BOUNDARY · CONTROL
Mistaking a successful build for an approved release
Build exit0 only describes the selected command. Independent checks may not have run, the inspected artifact may differ, or release approval may be separate. Marking the candidate production-ready then misstates gate coverage. In the failed-check branch the builder produces valid HTML, but the verifier compares expectedCoffee with actualTea and refuses promotion. This differs from a source compilation failure.
A matching artifact hash does not provide authorization, source review, or signed provenance. If manifest and artifact change together without control, their digest does not establish a trusted origin. Review which inputs/configuration produced the tested output and which policy receives that same candidate. baseline-a and candidate-a are inert local aliases, not production routes or release pointers.
Treating configuration as merely a byte boundary
Runtime configuration can change while a static package remains identical; equal bytes do not establish equal behavior. Conversely, embedding a secret in browser build-time config does not make it server-only. The fixture carries public values and uses a separate typed parser gate. Secret management retains the lifecycle boundaries of WEB-16.02; an environment name or .env syntax supplies neither a vault nor rotation.
When required theme.css is missing, the builder creates no archive candidate. An old candidate filename would not prove new output exists. Record the input set, candidate existence, actual digest, and verifier result separately. Temporary readback is useful evidence, but this branch establishes no deployment, application startup, external dependency reachability, or browser rendering.
3. Blue · Secure development & defense
Read every scenario without motion
Candidate controls
- Identify output bytes
These records come from the local static-file builder, HTML-title reader, hash calculation and typed config decoder. They observe no GitHub workflow, production environment or deployment logs. Normal entries are index.html and site.css. Output digests bind individual bytes and package digest binds packaging; the hash kinds are not interchangeable.
- Input/output manifest
- Two output digests + package identity
- Identity and content review
- Not yet evaluated
- Gate evidence
- Not yet evaluated
- Content observation
parsedTitle is Tea note and normal verification true. Digest equality answers byte identity; title checking answers content correctness. Both are bound to candidate-a.
- Input/output manifest
- Two output digests + package identity
- Identity and content review
- Title Tea note / candidate-a verified
- Gate evidence
- Not yet evaluated
- Negative controls
Coffee expectation is unverified and unpromoted; missing theme.css prevents verification. The two negative cases retain distinct causes behind a rejected release result.
- Input/output manifest
- Two output digests + package identity
- Identity and content review
- Title Tea note / candidate-a verified
- Gate evidence
- Mismatch vs missing input distinct
- Repeatability scope
repeatSameBytes is true for the supplied builder and inputs. It does not certify an external dependency supply chain, signed provenance or an entire reproducible repository build.
- Input/output manifest
- Selected repeat bytes / broader provenance absent
- Identity and content review
- Title Tea note / candidate-a verified
- Gate evidence
- Mismatch vs missing input distinct
- Configuration-influence record
Runtime configuration is associated separately from the static package. READ_ONLY parsing is public string comparison, not process-environment reading or applied production policy.
- Input/output manifest
- Selected repeat bytes / broader provenance absent
- Identity and content review
- Config identity separate from static bytes
- Gate evidence
- Mismatch vs missing input distinct
- Bounded local receipt
Entry allowlist, bytes, title and verifier result remain in one candidate record. The ledger retains deployed false; a local pass does not become public activation.
- Input/output manifest
- Selected repeat bytes / broader provenance absent
- Identity and content review
- Config identity separate from static bytes
- Gate evidence
- Local evidence bound / publication separate
Missing identity
- Build-success-only view
These records come from the local static-file builder, HTML-title reader, hash calculation and typed config decoder. They observe no GitHub workflow, production environment or deployment logs. The review sees only build success, without input manifest or output digest. The message cannot identify which candidate passed content verification.
- Input/output manifest
- Build success / candidate identity missing
- Identity and content review
- Not yet evaluated
- Gate evidence
- Not yet evaluated
- Do not treat expectation as observation
The normal packageSha256 belongs to the known fixture. Inserting it into an incomplete event would present unexamined output as the same candidate.
- Input/output manifest
- Build success / candidate identity missing
- Identity and content review
- Expected digest ≠ missing output evidence
- Gate evidence
- Not yet evaluated
- Promotion uncertainty
Verification execution, gate result and promotion remain UNKNOWN. The record retains compile success without adding approval or deployment outcomes.
- Input/output manifest
- Build success / candidate identity missing
- Identity and content review
- Expected digest ≠ missing output evidence
- Gate evidence
- Verifier/promotion/deployment UNKNOWN
- Required candidate binding
Input bytes/hashes, builder identity, configuration influence and output digest are needed. Independent checks must bind to the same output; a filename alone is not exact identity.
- Input/output manifest
- Needed: input/builder/config/output/check
- Identity and content review
- Expected digest ≠ missing output evidence
- Gate evidence
- Verifier/promotion/deployment UNKNOWN
- Gate-contradiction check
The selector looks for verified false with promoted true. Zero matches with missing records is not healthy-release evidence; observation coverage is needed separately.
- Input/output manifest
- Needed: input/builder/config/output/check
- Identity and content review
- Contradiction absent ≠ complete coverage
- Gate evidence
- Verifier/promotion/deployment UNKNOWN
- Question for the next evidence
New evidence must identify which candidate passed which gate. This event retains only its build message, adding no release-success claim without byte/source binding.
- Input/output manifest
- Needed: input/builder/config/output/check
- Identity and content review
- Contradiction absent ≠ complete coverage
- Gate evidence
- Collect exact candidate/check binding
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Fix the identity of the tested candidate
These records come from the local static-file builder, HTML-title reader, hash calculation and typed config decoder. They observe no GitHub workflow, production environment or deployment logs. Bind the input manifest, selected builder identity, config influence, and output digest in one record. Missing required input must prevent a candidate; partial output must not appear as a ready release. The fixture uses a fixed file set rather than arbitrary paths. Repeat builds yield equal bytes, while an ordinary title change alters index and package digests. The parser title and hash answer different questions: content expectations and exact output identity.
Check a declared archive-entry allowlist so source notes, test expectations, or secrets do not enter the package. Only index.html and site.css are included. Dependency caches and release artifacts have different lifecycles: build inputs need a regeneration path, while the release record preserves the inspected output. No tool installation or repository-pipeline change belongs to this teaching check.
Separate gate results from publication state
Distinguish candidate passed, check failed, missing input, and config mismatch. Neither source review nor a local build is publication. The supplied READ_ONLY parsing gate makes false genuinely false and rejects unexpected text. That is not a Node process.env read or production-policy enforcement; the source string semantics and own typed-adapter result are recorded separately.
Checking a build candidate and activating it on a route are different transitions. Release decisions use environment policy, rollback targets and verification of that same candidate together. This local ledger performs no deployment. The selector detects failed verification with promoted=true; a missing verifier record does not establish a successful release.
NOW APPLY IT TO THE CASE
Does the same package hash mean a successful release?
Two public inputs produce index.html and site.css. Tea note is bound to the correct candidate, while a check expecting Coffee note fails. Even with the same static package, parsing READ_ONLY as false or true describes different runtime behavior.
Evaluate the case data journey together with environment, dependency and telemetry context. Does an operational-success label establish every application outcome?
Open the related case file ↗READ THE EXAMPLE TOGETHER
Source / static artifact gate ledger
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"environments": {
"development": "author changes",
"test": "selected assertions",
"staging": "representative release-candidate review",
"production": "serves users; not activated here"
},
"inputs": {
"public-note.json": "{\"title\":\"Tea note\"}",
"theme.css": "body { color: #222; }\n"
},
"outputs": {
"index.html": "<!doctype html><html lang=\"en\"><head><link rel=\"stylesheet\" href=\"site.css\"></head><body><h1>Tea note</h1></body></html>",
"site.css": "body { color: #222; }\n"
},
"normal": {
"entries": [
"index.html",
"site.css"
],
"packageSha256": "23d0b6423be7f017c5578ccf073562921fe645210e2f0703e1ee2162d7c61a05",
"outputSha256": {
"index.html": "a16a5f8c563d184509983d42d01daa3fdf60fbf6d549f071b2c06204b4a3e9c0",
"site.css": "117f85041fb8bb248011e3ade19c2f8b567e9b4cbaa9cb9e9bb4fb3cabc8367e"
},
"repeatSameBytes": true,
"parsedTitle": "Tea note",
"verified": true,
"recordedLocalCandidate": "candidate-a",
"deployed": false
},
"gateFailed": {
"expectedTitle": "Coffee note",
"actualTitle": "Tea note",
"verified": false,
"promoted": false,
"localBaseline": "baseline-a"
},
"missingInput": {
"required": "theme.css",
"candidateCreated": false,
"verificationRun": false
},
"runtimeConfig": {
"READ_ONLY": "false",
"parsedReadOnly": false,
"alternateText": "true",
"alternateReadOnly": true,
"sameStaticPackage": true,
"configIsPublic": true,
"processEnvironmentRead": false
},
"bundling": {
"dependencyGraphExample": {
"entry": "main-demo",
"imports": [
"label-demo"
],
"labelDemoImports": []
},
"nativeFixture": "static-file packaging, not a JS module bundler",
"esbuildExecuted": false
},
"limits": {
"repositoryBuildRun": false,
"githubWorkflowRun": false,
"deploymentRun": false,
"browserRenderRun": false,
"secretRead": false,
"signedProvenanceVerified": false
},
"selector": {
"language": "XPath",
"xml": "<audit><candidate verified=\"false\" promoted=\"false\"/></audit>",
"xpath": "count(/audit/candidate[@verified='false' and @promoted='true'])",
"expected": 0,
"positiveFixtureXml": "<audit><candidate verified=\"false\" promoted=\"true\"/></audit>",
"positiveExpected": 1,
"scope": "Own inert decision observations, not vendor log fields.",
"missingFieldBehavior": "Missing observation is insufficient evidence; zero matches alone proves no healthy runtime/control."
}
}- inputs/outputs
- Own public source bytes and generated HTML/CSS bytes.
- normal/gateFailed
- Digest identity and independent content checks are distinct decisions.
- runtimeConfig/bundling
- Runtime config separate; static ZIP packaging differs from JS bundling.
- selector/limits
- Inert gate observation; no repo build, deployment, or secret read.
Actual own temporary static builder, HTML parser, ZIP, and hash checks only. No repository build, real bundler, GitHub workflow, deployment, runtime server, or Browser render.
Two reality checks
Build exit0 and an artifact hash mean approved deployment.
Build execution, exact bytes, verifier results, and publication/approval need different evidence.
An equal artifact hash guarantees equal environment behavior.
Runtime config and dependencies can differ; public config types and authority need separate checks.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
The expected title is Coffee note, but the package contains Tea note. May this candidate replace the baseline?
- Yes. Creating the package satisfies every acceptance condition.
- No. verified=false and promoted=false.
Read the explained answer
No. verified=false and promoted=false. — Verification failed because the expected title does not match. baseline-a is retained; creating a package alone is not release approval.
What does this record show about reproducible packaging and an actual deployment?
Selected lesson artifact fields; teaching example
- normal.entries
- ["index.html","site.css"]
- normal.repeatSameBytes
- true
- normal.verified
- true
- normal.deployed
- false
- Repeated bytes match and verification passed; no deployment occurred.
- Matching hashes prove production users received this version.
Read the explained answer
Repeated bytes match and verification passed; no deployment occurred. — repeatSameBytes=true and verified=true describe the local candidate. With deployed=false, this is not a production release.
READ_ONLY is the string "false", and alternateText is "true". Why can the same static package support different runtime behavior?
Read the explained answer
A nonempty string is not automatically the intended boolean true. This example maps "false" to parsedReadOnly=false and "true" to alternateReadOnly=true. The config can change while sameStaticPackage=true. The config is public; no real process environment or secret is read. Static-file packaging is also not an executed JS module bundler.
□ I separated config text from its parsed boolean.
□ I did not equate unchanged package bytes with unchanged runtime config.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
Sources and scope
- GitHub Docs — WorkflowsAbout workflows · Workflow basics · Workflow triggers
- GitHub Docs — Workflow artifactsAbout workflow artifacts · Artifacts versus dependency caching · Generating artifact attestations for builds
- GitHub Docs — Managing environments for deploymentOpening paragraphs: deployment protection rules · Creating an environment · How environments relate to deployments
- esbuild — APIBuild · Bundle · Non-analyzable imports
- Node.js v26.11.1 — Environment Variablesprocess.env · Variable Values
- Python 3.14 — hashlibUsage · Constructors
- GitHub Docs — Continuous integrationAbout continuous integration · About continuous integration using GitHub Actions
- GitHub Docs — Continuous deploymentAbout continuous deployment · About continuous deployment using GitHub Actions
- Martin Fowler — Continuous Delivery (historical definition, 2013; updated 2014)Opening definition and indicators · Continuous Delivery versus Continuous Deployment (paragraph starting Continuous Delivery is sometimes confused)