Skip to content

Commit 796d662

Browse files
authored
Stop tracking build artifacts (docs/, coverage/) (#39)
* chore: stop tracking build artifacts (docs/, coverage/) * fix: use root-relative /docs/ in .gitignore, correct plan coverage text * chore: add PR review documentation for build artifact separation
1 parent c035f25 commit 796d662

8 files changed

Lines changed: 598 additions & 6 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Specification Quality Checklist: Build Artifact Separation
2+
3+
**Purpose**: Validate specification completeness and quality before proceeding to planning
4+
**Created**: 2026-04-13
5+
**Feature**: [spec.md](../spec.md)
6+
7+
## Content Quality
8+
9+
- [x] No implementation details (languages, frameworks, APIs)
10+
- [x] Focused on user value and business needs
11+
- [x] Written for non-technical stakeholders
12+
- [x] All mandatory sections completed
13+
14+
## Requirement Completeness
15+
16+
- [x] No [NEEDS CLARIFICATION] markers remain
17+
- [x] Requirements are testable and unambiguous
18+
- [x] Success criteria are measurable
19+
- [x] Success criteria are technology-agnostic (no implementation details)
20+
- [x] All acceptance scenarios are defined
21+
- [x] Edge cases are identified
22+
- [x] Scope is clearly bounded
23+
- [x] Dependencies and assumptions identified
24+
25+
## Feature Readiness
26+
27+
- [x] All functional requirements have clear acceptance criteria
28+
- [x] User scenarios cover primary flows
29+
- [x] Feature meets measurable outcomes defined in Success Criteria
30+
- [x] No implementation details leak into specification
31+
32+
## Notes
33+
34+
- Spec uses quick-spec template (appropriate for build/tooling infrastructure change)
35+
- The spec references specific filenames (`docs/`, `coverage/`) which are factual project artifacts, not implementation prescriptions
36+
- Risk is medium due to deployment pipeline dependency; constraints section captures this clearly
37+
- No [NEEDS CLARIFICATION] markers — the intent, scope, and constraints are well-defined from codebase analysis
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Implementation Plan: Build Artifact Separation
2+
3+
**Branch**: `001-build-artifact-separation` | **Date**: 2026-04-13 | **Spec**: [spec.md](spec.md)
4+
**Input**: Feature specification from `/specs/001-build-artifact-separation/spec.md`
5+
6+
## Summary
7+
8+
Separate build artifacts (`docs/`, `coverage/`) from source files by adding them to `.gitignore` and untracking them from git. The CI/CD pipeline already builds from source, so committed build output is redundant and creates ~40+ file changes per build. This is a configuration-only change with no source code modifications.
9+
10+
## Technical Context
11+
12+
**Language/Version**: TypeScript 5.x, Node.js 18+
13+
**Primary Dependencies**: Vite (build tool), React (framework), Azure Static Web Apps (hosting)
14+
**Storage**: N/A (no data storage changes)
15+
**Testing**: Vitest (existing test runner — no new tests needed for config change)
16+
**Target Platform**: Azure Static Web Apps (production), local dev server (development)
17+
**Project Type**: Single web application (React SPA)
18+
**Performance Goals**: N/A (no runtime changes)
19+
**Constraints**: Azure SWA CI/CD must continue to work; local dev workflow must remain functional
20+
**Scale/Scope**: Configuration files only — `.gitignore`, git index, README
21+
22+
## Constitution Check
23+
24+
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
25+
26+
| Principle | Status | Notes |
27+
|-----------|--------|-------|
28+
| I. Type Safety | PASS | No code changes — config files only |
29+
| II. Code Quality & Linting | PASS | No linted files affected |
30+
| III. Testing | PASS | No new code to test; coverage reports remain generated locally |
31+
| IV. Documentation | PASS | README will be updated in same commit per constitution |
32+
| V. Component Architecture | PASS | No architectural changes |
33+
| VI. Error Handling | PASS | No runtime changes |
34+
| VII. Logging | PASS | No runtime changes |
35+
| VIII. Input Validation | PASS | No runtime changes |
36+
| IX. Styling | PASS | No styling changes |
37+
| X. Code Quality Gates | PASS | Pre-commit hooks unaffected; `.gitignore` change is additive |
38+
39+
**Gate result**: ALL PASS — no violations to justify.
40+
41+
## Project Structure
42+
43+
### Documentation (this feature)
44+
45+
```text
46+
specs/001-build-artifact-separation/
47+
├── spec.md # Feature specification
48+
├── plan.md # This file
49+
├── research.md # Phase 0 findings (minimal — no unknowns)
50+
├── checklists/
51+
│ └── requirements.md # Quality checklist
52+
└── tasks.md # Phase 2 output (created by /devspark.tasks)
53+
```
54+
55+
### Source Code (repository root)
56+
57+
No source code changes. Only configuration files are modified:
58+
59+
```text
60+
.gitignore # ADD: docs/ entry
61+
README.md # UPDATE: note about build artifacts
62+
```
63+
64+
Git operations (not file edits):
65+
```text
66+
git rm -r --cached docs/ # Untrack build output
67+
git rm -r --cached coverage/ # Untrack coverage reports (already in .gitignore but still tracked)
68+
```
69+
70+
**Structure Decision**: This feature modifies no source directories. The existing `src/``docs/` build pipeline is preserved exactly as-is; only the git tracking of `docs/` output changes.
71+
72+
## Phase 0: Research
73+
74+
No NEEDS CLARIFICATION items in Technical Context. Research was completed during spec creation by examining:
75+
76+
1. **CI/CD workflow** ([.github/workflows/azure-static-web-apps-gentle-smoke-063be0b10.yml](../../.github/workflows/azure-static-web-apps-gentle-smoke-063be0b10.yml)): Confirmed `skip_app_build: false` and `app_build_command: "npm run build"` — CI builds from source, does not depend on committed `docs/`
77+
2. **SWA CLI config** ([swa-cli.config.json](../../swa-cli.config.json)): Uses `appBuildCommand: "npm run build"` — builds before serving
78+
3. **Vite config** ([vite.config.ts](../../vite.config.ts)): `outDir: "docs"` with hash-based filenames — confirms the churn source
79+
4. **Current `.gitignore`**: `coverage/` is listed but `docs/` is not; `coverage/` directory is still tracked despite being in `.gitignore` (was added to git before the ignore rule)
80+
81+
**Decision**: No unknowns remain. Proceed directly to implementation.
82+
83+
See [research.md](research.md) for consolidated findings.
84+
85+
## Phase 1: Design
86+
87+
### Data Model
88+
89+
N/A — no data entities affected. No `data-model.md` needed.
90+
91+
### Contracts
92+
93+
N/A — no external interfaces change. No `contracts/` needed.
94+
95+
### Implementation Steps
96+
97+
#### Step 1: Update `.gitignore`
98+
99+
Add `docs/` to the "Build artifacts" section. The entry should be `/docs/` (root-relative) to avoid ignoring any nested `docs/` directories in unlikely future scenarios.
100+
101+
Current state:
102+
```gitignore
103+
# Build artifacts
104+
/build
105+
/.next
106+
/out
107+
coverage/
108+
```
109+
110+
Target state:
111+
```gitignore
112+
# Build artifacts
113+
/build
114+
/.next
115+
/out
116+
coverage/
117+
docs/
118+
```
119+
120+
#### Step 2: Untrack `docs/` from git
121+
122+
```bash
123+
git rm -r --cached docs/
124+
```
125+
126+
This removes `docs/` from the git index without deleting local files. After this, git will no longer track the ~40+ build output files.
127+
128+
#### Step 3: Untrack `coverage/` from git
129+
130+
```bash
131+
git rm -r --cached coverage/
132+
```
133+
134+
The `coverage/` entry already exists in `.gitignore`. Note: `coverage/` was never actually tracked in git (the ignore rule was added before any coverage files were committed), so this step is a no-op.
135+
136+
#### Step 4: Update README.md
137+
138+
Add a brief note in the development section explaining that `docs/` is a build artifact directory generated by `npm run build`, not committed to git. Contributors need to run `npm run build` before `npm run preview`.
139+
140+
#### Step 5: Commit and validate
141+
142+
```bash
143+
git add .gitignore README.md
144+
git commit -m "chore: stop tracking build artifacts (docs/, coverage/)"
145+
npm run build
146+
git status # Should show no changes in docs/
147+
```
148+
149+
### Vite Config: `createNoJekyllFile` Plugin
150+
151+
The Vite config includes a `createNoJekyllFile()` plugin that writes `docs/.nojekyll` on each build. This was needed for GitHub Pages (which uses Jekyll). Since the project now deploys to Azure Static Web Apps (not GitHub Pages), this plugin is harmless but unnecessary. **No action needed for this feature** — it can be cleaned up separately if desired.
152+
153+
## Post-Design Constitution Re-Check
154+
155+
| Principle | Status | Notes |
156+
|-----------|--------|-------|
157+
| IV. Documentation | PASS | README updated in same commit as code change |
158+
| X. Code Quality Gates | PASS | `.gitignore` is additive; no existing gates broken |
159+
160+
All gates pass. Ready for `/devspark.tasks`.
161+
162+
## Complexity Tracking
163+
164+
No constitution violations. Table not needed.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Research: Build Artifact Separation
2+
3+
**Feature**: 001-build-artifact-separation
4+
**Date**: 2026-04-13
5+
6+
## Findings
7+
8+
### 1. CI/CD Pipeline Independence from Committed Build Output
9+
10+
**Decision**: Safe to remove `docs/` from git tracking.
11+
**Rationale**: The Azure Static Web Apps GitHub Actions workflow explicitly sets `skip_app_build: false` and `app_build_command: "npm run build"`. The deployment action builds from source on every push — it never reads pre-existing files from `docs/`.
12+
**Alternatives considered**: None — this is a factual verification, not a design choice.
13+
14+
### 2. Local SWA CLI Behavior
15+
16+
**Decision**: No changes needed to `swa-cli.config.json`.
17+
**Rationale**: The config specifies `appBuildCommand: "npm run build"`, meaning the CLI triggers a build before serving. It does not assume `docs/` exists prior to invocation.
18+
**Alternatives considered**: Could add `outputLocation: "docs"` explicitly, but it's already set and correct.
19+
20+
### 3. Coverage Directory Tracking
21+
22+
**Decision**: Untrack `coverage/` in the same commit.
23+
**Rationale**: `coverage/` is already in `.gitignore` (line 50) but was committed to git before the rule was added. It contains test coverage HTML reports that are build artifacts. Currently tracked files: `coverage-final.json`, `lcov.info`, HTML reports.
24+
**Alternatives considered**: Leave it tracked — rejected because it creates the same noise problem.
25+
26+
### 4. Vite `createNoJekyllFile` Plugin
27+
28+
**Decision**: Leave as-is (no action in this feature).
29+
**Rationale**: This plugin writes `docs/.nojekyll` for GitHub Pages compatibility. The project now uses Azure SWA, so it's unnecessary but harmless. Removing it is a separate cleanup concern.
30+
**Alternatives considered**: Remove the plugin — deferred to avoid scope creep.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
classification: quick-spec
3+
risk_level: medium
4+
target_workflow: specify-light
5+
required_artifacts: intent, action-plan
6+
recommended_next_step: plan
7+
required_gates: checklist
8+
---
9+
10+
# Quick Specification: Build Artifact Separation
11+
12+
**Feature Branch**: `001-build-artifact-separation`
13+
**Created**: 2026-04-13
14+
**Status**: Complete <!-- Valid: Draft | In Progress | Complete -->
15+
**Input**: User description: "Refactor files and build process to separate source files from build artifacts. Prevent every build from creating git noise that distracts from meaningful changes. Clean separation between source and built output so .gitignore can exclude build artifacts."
16+
17+
## Intent
18+
19+
Every `npm run build` produces a `docs/` directory with hash-based filenames (e.g., `About-DUW_-ayh.js`). Because `docs/` is tracked in git, **each build generates ~40+ changed files** in git status — all deletions of old hashed files and additions of new ones. This noise obscures actual meaningful code changes, pollutes pull request diffs, and makes commit history harder to review.
20+
21+
The `docs/` directory is the Vite build output consumed by Azure Static Web Apps. The CI/CD pipeline (GitHub Actions) already runs `npm run build` and deploys from `docs/` — meaning the committed `docs/` folder is redundant. The `coverage/` directory (test coverage reports) is also partially tracked and creates similar noise.
22+
23+
This change will establish a clean boundary: **source files are committed, build artifacts are not**.
24+
25+
## Scope
26+
27+
- **In scope:**
28+
- Add `docs/` to `.gitignore` so Vite build output is never committed
29+
- Add `coverage/` to `.gitignore` (test coverage reports are build artifacts)
30+
- Remove `docs/` and `coverage/` from git tracking (untrack without deleting local files)
31+
- Verify the Azure Static Web Apps CI/CD workflow builds from source and does not depend on a pre-committed `docs/` folder
32+
- Update `swa-cli.config.json` if needed to ensure local SWA CLI still works with the build-on-demand model
33+
- Update any documentation that references the `docs/` folder as a deployment target requiring commits
34+
35+
- **Out of scope:**
36+
- Changing the Vite `outDir` configuration (keeping `docs/` as the build output directory is fine)
37+
- Changing the CI/CD workflow structure or deployment provider
38+
- Modifying the build process itself (scripts, plugins, optimizations)
39+
- Changing the `public/` or `src/` source file structure
40+
41+
## Constraints
42+
43+
- **Azure Static Web Apps deployment must not break.** The GitHub Actions workflow uses `output_location: "docs"` and `app_build_command: "npm run build"` — it builds from source in CI. Removing committed `docs/` must not affect this.
44+
- **Local development workflow must remain functional.** `npm run dev`, `npm run build`, and `npm run preview` must continue to work. The SWA CLI (`swa start`) must still find build output.
45+
- **Constitution compliance:** No new test coverage gaps. Build/config changes must be validated.
46+
- **Backward compatibility:** Contributors who `git pull` after this change will no longer have a pre-built `docs/` folder. The README should note that `npm run build` is required before `npm run preview`.
47+
48+
## Action Plan
49+
50+
1. **Update `.gitignore`** — Add `docs/` and ensure `coverage/` entries cover all coverage output
51+
2. **Untrack `docs/` from git** — Run `git rm -r --cached docs/` to stop tracking without deleting local files
52+
3. **Untrack `coverage/` from git** — Run `git rm -r --cached coverage/` to stop tracking without deleting local files
53+
4. **Verify CI/CD pipeline** — Confirm the Azure Static Web Apps workflow builds from source (`skip_app_build: false`, `app_build_command: "npm run build"`) and does not expect pre-committed build output
54+
5. **Verify local SWA CLI** — Confirm `swa-cli.config.json` uses `appBuildCommand` so it builds before serving, not relying on pre-existing `docs/`
55+
6. **Update README** — Add a note that `docs/` is a build artifact (not committed) and `npm run build` must be run before previewing locally
56+
7. **Commit and validate** — Commit the `.gitignore` and untrack changes, then verify a clean `git status` after running `npm run build`
57+
58+
## Validation Notes
59+
60+
- After the change, running `npm run build` should produce **zero git-tracked file changes** in `docs/`
61+
- `git status` after a build should show only source file modifications (if any)
62+
- The Azure Static Web Apps CI/CD pipeline must successfully build and deploy on push to `main`
63+
- `npm run dev`, `npm run build`, `npm run preview`, and `swa start` must all function correctly
64+
- A fresh clone followed by `npm install && npm run build` must produce a working site
65+
- How does system handle [error scenario]?
66+
67+
## Requirements *(mandatory)*
68+
69+
<!--
70+
ACTION REQUIRED: The content in this section represents placeholders.
71+
Fill them out with the right functional requirements.
72+
-->
73+
74+
### Functional Requirements
75+
76+
- **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"]
77+
- **FR-002**: System MUST [specific capability, e.g., "validate email addresses"]
78+
- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"]
79+
- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"]
80+
- **FR-005**: System MUST [behavior, e.g., "log all security events"]
81+
82+
*Example of marking unclear requirements:*
83+
84+
- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?]
85+
- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified]
86+
87+
### Key Entities *(include if feature involves data)*
88+
89+
- **[Entity 1]**: [What it represents, key attributes without implementation]
90+
- **[Entity 2]**: [What it represents, relationships to other entities]
91+
92+
## Success Criteria *(mandatory)*
93+
94+
<!--
95+
ACTION REQUIRED: Define measurable success criteria.
96+
These must be technology-agnostic and measurable.
97+
-->
98+
99+
### Measurable Outcomes
100+
101+
- **SC-001**: [Measurable metric, e.g., "Users can complete account creation in under 2 minutes"]
102+
- **SC-002**: [Measurable metric, e.g., "System handles 1000 concurrent users without degradation"]
103+
- **SC-003**: [User satisfaction metric, e.g., "90% of users successfully complete primary task on first attempt"]
104+
- **SC-004**: [Business metric, e.g., "Reduce support tickets related to [X] by 50%"]

0 commit comments

Comments
 (0)