diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ae2d97c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,115 @@ +name: Release + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +permissions: + contents: write + +jobs: + lint: + name: Lint & Format Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + - run: npm ci + - run: npm run lint + - run: npm run format:check + + test: + name: Unit & Integration Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + - run: npm ci + - run: npm run test:unit + - run: npm run test:integration + + build: + name: Build & Bundle Size Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + - run: npm ci + - run: npm run build + - name: Check bundle size + run: npm run size-check + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + + release: + name: Create GitHub Release + runs-on: ubuntu-latest + needs: [lint, test, build] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - name: Extract version from tag + id: version + run: | + VERSION=${GITHUB_REF_NAME#v} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Releasing version: $VERSION" + + - name: Check if package.json version needs update + id: check-version + run: | + CURRENT_VERSION=$(node -p "require('./package.json').version") + TAG_VERSION=${{ steps.version.outputs.version }} + if [ "$CURRENT_VERSION" = "$TAG_VERSION" ]; then + echo "needs_update=false" >> $GITHUB_OUTPUT + echo "Package.json already at version $TAG_VERSION" + else + echo "needs_update=true" >> $GITHUB_OUTPUT + echo "Package.json version $CURRENT_VERSION differs from tag $TAG_VERSION" + fi + + - name: Update package.json version + if: steps.check-version.outputs.needs_update == 'true' + run: | + npm version ${{ steps.version.outputs.version }} --no-git-tag-version + echo "Updated package.json to version ${{ steps.version.outputs.version }}" + + - name: Commit and push version update + if: steps.check-version.outputs.needs_update == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add package.json package-lock.json + git commit -m "chore(release): ${{ github.ref_name }}" + git push origin HEAD:main + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + files: | + dist/sonar-quiz.iife.js + dist/sonar-quiz.iife.js.map + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CLAUDE.md b/CLAUDE.md index 784f89c..9076a65 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -557,6 +557,8 @@ function getStorageKey(release: ReleaseId, serviceId: ServiceId): string { - IndexedDB (primary) - obfuscation at adapter layer; sessionStorage unchanged (009-encrypt-stored-data) - CSS3 + TypeScript 5.x (for JS integration) + Existing DITA template CSS (`f13ldman.css`), Lit 3.x components (010-css-answer-hiding) - N/A (CSS-only feature) (010-css-answer-hiding) +- YAML (GitHub Actions workflows), Bash (scripts) + GitHub Actions (actions/checkout, actions/setup-node, softprops/action-gh-release) (011-release-automation) +- N/A (CI/CD infrastructure only) (011-release-automation) ## Recent Changes - 001-security-refactor: Added TypeScript 5.x / JavaScript ES2020+ + Lit 3.0 (Web Components), Vite 5.x (build), Vitest (testing) diff --git a/README.md b/README.md index 9f530a4..1d3c718 100644 --- a/README.md +++ b/README.md @@ -123,10 +123,22 @@ npm run build:dita This copies `dist/sonar-quiz.iife.js` to `dita/template/resources/` for inclusion in WebHelp output. See [dita/README.md](./dita/README.md) for DITA authoring guidelines and template customization. +## Releases + +Releases are created by pushing a version tag to the main branch: + +```bash +git tag v0.2.0 +git push origin v0.2.0 +``` + +See [docs/RELEASE.md](./docs/RELEASE.md) for complete release instructions. + ## Project Documentation | Document | Description | |----------|-------------| +| [docs/RELEASE.md](./docs/RELEASE.md) | Release process and versioning guide | | [System_Requirements.md](./System_Requirements.md) | Functional requirements, user roles, data model, and authoring rules | | [Technical_Design.md](./Technical_Design.md) | Architecture, technology decisions, packaging, integration, and acceptance criteria | | [ARCHITECTURE_FLOWS.md](./ARCHITECTURE_FLOWS.md) | Event flows, login processes, DOM patterns, and service interactions | diff --git a/docs/RELEASE.md b/docs/RELEASE.md new file mode 100644 index 0000000..a982753 --- /dev/null +++ b/docs/RELEASE.md @@ -0,0 +1,133 @@ +# Release Process + +This document describes how to create releases for the BrowserTest (Sonar Quiz System) project. + +## Overview + +Releases are automated via GitHub Actions. When you push a version tag to the main branch, a workflow automatically: + +1. Runs all CI checks (lint, tests, build) +2. Builds the production bundle +3. Creates a GitHub Release with release notes +4. Attaches the bundle artifacts + +## Versioning + +This project uses [Semantic Versioning](https://semver.org/): + +- **MAJOR** (`X.0.0`): Breaking changes +- **MINOR** (`0.X.0`): New features (backward-compatible) +- **PATCH** (`0.0.X`): Bug fixes (backward-compatible) + +## How to Create a Release + +### Prerequisites + +- You must have push access to the repository +- The main branch must be in a passing CI state + +### Steps + +1. **Ensure you're on the latest main branch:** + + ```bash + git checkout main + git pull origin main + ``` + +2. **Create and push a version tag:** + + ```bash + git tag v0.2.0 + git push origin v0.2.0 + ``` + +3. **Monitor the release workflow:** + - Go to the [Actions tab](../../actions) + - Watch the "Release" workflow complete (~3-5 minutes) + +4. **Verify the release:** + - Go to the [Releases page](../../releases) + - Confirm the new release exists with: + - Correct version number + - Auto-generated release notes + - Attached `sonar-quiz.iife.js` bundle + - Attached `sonar-quiz.iife.js.map` source map + +### Using GitHub CLI + +```bash +# Create tag and release in one command +gh release create v0.2.0 --generate-notes +``` + +## Version Tag Format + +Tags **must** follow semantic versioning format: `vX.Y.Z` + +| Valid Tags | Invalid Tags | +|------------|--------------| +| `v0.1.0` | `0.1.0` (missing 'v' prefix) | +| `v1.0.0` | `v1.0` (missing patch number) | +| `v10.20.30` | `release-1.0.0` (wrong prefix) | +| `v2.0.0-beta.1` | N/A (pre-release not currently supported) | + +## What's Included in a Release + +Each release includes: + +- **sonar-quiz.iife.js** - The production bundle (IIFE format) +- **sonar-quiz.iife.js.map** - Source map for debugging +- **Source code** - Automatically generated zip and tar.gz archives + +## Troubleshooting + +### Tag pushed but no release created + +1. **Check tag format** - Must match `vX.Y.Z` pattern exactly +2. **Verify tag was pushed:** + ```bash + git ls-remote --tags origin | grep v0.2.0 + ``` +3. **Check Actions tab** - Look for workflow failures +4. **Review CI status** - Release won't be created if lint/tests/build fail + +### CI checks failing after tag push + +The release workflow runs the full CI suite. If it fails: + +1. Fix the issues on main branch +2. Delete the failed tag: + ```bash + git push --delete origin v0.2.0 + git tag -d v0.2.0 + ``` +3. Create the tag again after fixes are merged + +### Re-releasing the same version + +If you need to re-release (e.g., release was incomplete): + +```bash +# Delete the existing release +gh release delete v0.2.0 --yes + +# Delete the remote tag +git push --delete origin v0.2.0 + +# Delete local tag +git tag -d v0.2.0 + +# Create new tag and push +git tag v0.2.0 +git push origin v0.2.0 +``` + +### Package.json version mismatch + +The release workflow automatically updates `package.json` to match the tag version. If there's a mismatch, the tag version is the source of truth. + +## Related Documentation + +- [CLAUDE.md](../CLAUDE.md) - Development guidelines and project architecture +- [README.md](../README.md) - Project overview and quick start diff --git a/specs/011-release-automation/checklists/requirements.md b/specs/011-release-automation/checklists/requirements.md new file mode 100644 index 0000000..d935785 --- /dev/null +++ b/specs/011-release-automation/checklists/requirements.md @@ -0,0 +1,36 @@ +# Specification Quality Checklist: Release Automation + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2025-11-28 +**Feature**: [spec.md](../spec.md) + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- All items pass validation +- Spec is ready for `/speckit.clarify` or `/speckit.plan` +- Conventional commits assumption documented - may need user confirmation during planning diff --git a/specs/011-release-automation/plan.md b/specs/011-release-automation/plan.md new file mode 100644 index 0000000..51d065c --- /dev/null +++ b/specs/011-release-automation/plan.md @@ -0,0 +1,67 @@ +# Implementation Plan: Release Automation + +**Branch**: `011-release-automation` | **Date**: 2025-11-28 | **Spec**: [spec.md](./spec.md) +**Input**: Feature specification from `/specs/011-release-automation/spec.md` + +## Summary + +Establish CI/CD automation for semantic versioning releases via GitHub Actions. Releases are triggered by pushing a `vX.Y.Z` tag to the main branch. The workflow validates CI checks, builds the bundle, updates package.json to match the tag version, and creates a GitHub Release with artifacts attached. + +## Technical Context + +**Language/Version**: YAML (GitHub Actions workflows), Bash (scripts) +**Primary Dependencies**: GitHub Actions (actions/checkout, actions/setup-node, softprops/action-gh-release) +**Storage**: N/A (CI/CD infrastructure only) +**Testing**: Tag push to trigger workflow, verify release creation +**Target Platform**: GitHub Actions runners (ubuntu-latest) +**Project Type**: Single project with existing CI workflows +**Performance Goals**: Release workflow completes in <5 minutes +**Constraints**: Must run all CI checks before release; tag is source of truth for version + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +- [x] **Offline-First**: N/A - CI/CD infrastructure, not runtime code. Does not affect offline operation. +- [x] **Progressive Enhancement**: N/A - No changes to runtime behavior or DITA enhancement. +- [x] **Test-Driven Development**: Workflow validated via tag push testing before merge. +- [x] **Phase-Gated Delivery**: Clear exit criteria: workflow runs, release created with artifacts. +- [x] **Performance Constraints**: N/A - Does not affect bundle size or runtime performance. +- [x] **Data Isolation**: N/A - No user data involved. +- [x] **Zero Configuration**: N/A - Deployment infrastructure, not runtime script. + +**All gates pass** - This feature is purely CI/CD infrastructure with no impact on the constitution's runtime constraints. + +## Project Structure + +### Documentation (this feature) + +```text +specs/011-release-automation/ +├── plan.md # This file +├── research.md # Phase 0 output +├── data-model.md # N/A - no data entities +├── quickstart.md # Release instructions +├── contracts/ # N/A - no API contracts +└── tasks.md # Phase 2 output +``` + +### Source Code (repository root) + +```text +.github/workflows/ +├── ci.yml # Existing CI workflow (lint, test, build) +├── pages.yml # Existing GitHub Pages deployment +├── pr-preview.yml # Existing PR preview deployment +├── pr-preview-comment.yml +└── release.yml # NEW: Release automation workflow (tag-triggered) + +docs/ +└── RELEASE.md # NEW: Release process documentation +``` + +**Structure Decision**: Single new workflow file plus documentation. Follows existing GitHub Actions patterns established in ci.yml. + +## Complexity Tracking + +No constitution violations. Feature is infrastructure-only. diff --git a/specs/011-release-automation/quickstart.md b/specs/011-release-automation/quickstart.md new file mode 100644 index 0000000..1e3d499 --- /dev/null +++ b/specs/011-release-automation/quickstart.md @@ -0,0 +1,87 @@ +# Quickstart: Release Automation + +## Creating a Release + +### Via Git Tag (Recommended) + +```bash +# 1. Ensure you're on main branch with latest changes +git checkout main +git pull origin main + +# 2. Create and push a version tag +git tag v0.1.5 +git push origin v0.1.5 + +# 3. Watch the release workflow +# GitHub Actions automatically triggers on tag push +# Release appears at Releases page in ~3-5 minutes +``` + +### Via GitHub CLI + +```bash +# Create and push tag in one command +gh release create v0.1.5 --generate-notes +``` + +**Note**: The workflow triggers automatically when you push a `vX.Y.Z` tag. No manual workflow dispatch needed. + +## Version Format + +Tags MUST follow semantic versioning format: `vX.Y.Z` + +| Valid | Invalid | +|-------|---------| +| `v0.1.5` | `0.1.5` (missing 'v') | +| `v1.0.0` | `v1.0` (missing patch) | +| `v10.20.30` | `release-1.0.0` (wrong prefix) | + +## What Gets Released + +- **sonar-quiz.iife.js** - Production bundle +- **sonar-quiz.iife.js.map** - Source map +- **Source code** - Auto-generated zip/tar.gz + +## Workflow Diagram + +``` +tag push → lint → test → build → release + ↓ + artifact upload + ↓ + package.json sync +``` + +## Troubleshooting + +### Tag pushed but no release created +- Check tag format matches `vX.Y.Z` pattern +- Verify tag was pushed to origin: `git ls-remote --tags origin` +- Check Actions tab for workflow failures + +### CI checks failing +Release won't be created if lint, tests, or build fail. Fix the issues on main first, delete the tag, then re-tag. + +```bash +# Delete remote tag +git push --delete origin v0.1.5 + +# Delete local tag +git tag -d v0.1.5 + +# Fix issues, then re-tag +git tag v0.1.5 +git push origin v0.1.5 +``` + +### Want to re-release same version +Delete the existing release and tag first: + +```bash +# Delete release via CLI +gh release delete v0.1.5 + +# Delete remote tag +git push --delete origin v0.1.5 +``` diff --git a/specs/011-release-automation/research.md b/specs/011-release-automation/research.md new file mode 100644 index 0000000..5ab1aaa --- /dev/null +++ b/specs/011-release-automation/research.md @@ -0,0 +1,120 @@ +# Research: Release Automation + +**Feature**: 011-release-automation +**Date**: 2025-11-28 + +## Research Questions + +### 1. GitHub Actions Release Strategy + +**Decision**: Use `softprops/action-gh-release` for GitHub Release creation + +**Rationale**: +- Most popular and well-maintained action for GitHub releases (17k+ stars) +- Supports automatic changelog generation from git commits +- Handles asset uploads (bundle artifacts) +- Works seamlessly with tag-triggered workflows +- Alternative: manual `gh release create` commands would work but require more scripting + +**Alternatives Considered**: +- `ncipollo/release-action`: Similar features, slightly less popular +- Manual `gh` CLI: More flexible but requires more maintenance +- `release-drafter/release-drafter`: Better for draft-based workflows, overkill here + +### 2. Workflow Trigger Mechanism + +**Decision**: Use tag push trigger with pattern matching for `v*` tags + +**Rationale**: +- User preference: pushing a tag like `v0.1.5` triggers the release +- Simple and intuitive - version is explicit in the tag +- No need for version inference from commits +- Matches common open-source project patterns + +**Implementation**: +```yaml +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' +``` + +This pattern matches: +- `v0.1.5` ✓ +- `v1.0.0` ✓ +- `v10.20.30` ✓ +- `v1.0` ✗ (invalid - must have 3 parts) +- `release-1.0.0` ✗ (must start with 'v') + +### 3. Version Extraction from Tag + +**Decision**: Extract version from `GITHUB_REF_NAME` environment variable + +**Rationale**: +- GitHub Actions provides the tag name directly +- Strip leading 'v' for package.json update: `${GITHUB_REF_NAME#v}` +- No complex parsing needed + +**Example**: +```bash +# Tag: v0.1.5 +VERSION=${GITHUB_REF_NAME#v} # Results in: 0.1.5 +``` + +### 4. CI Check Enforcement + +**Decision**: Run full CI suite within release workflow before creating release + +**Rationale**: +- Ensures all tests pass before any release artifacts are created +- Prevents invalid releases if tests fail +- Uses same jobs as ci.yml (lint, test, build) as reusable steps +- Only proceeds to release creation if all checks pass + +**Implementation**: +- Release job has `needs: [lint, test, build]` dependency +- Build job uploads artifacts; release job downloads and attaches them + +### 5. Artifact Handling + +**Decision**: Build bundle in workflow, attach as release asset + +**Rationale**: +- Uses existing `npm run build` which produces `dist/sonar-quiz.iife.js` +- Bundle is the primary deliverable for integrators +- Source code archives are automatically created by GitHub + +**Assets to attach**: +- `sonar-quiz.iife.js` (main bundle) +- `sonar-quiz.iife.js.map` (source map for debugging) + +### 6. Package.json Version Update + +**Decision**: Update package.json to match tag version and commit back to main + +**Rationale**: +- Keeps package.json in sync with git tags (tag is source of truth) +- Standard practice for JS projects +- Commit message: `chore(release): v{version}` +- Pushed to main branch after successful release + +**Workflow sequence**: +1. Tag triggers workflow +2. Run CI checks (lint, test, build) +3. Update package.json version to match tag +4. Commit version update to main +5. Create GitHub Release with assets + +### 7. Release Notes Generation + +**Decision**: Auto-generate from commits using `softprops/action-gh-release` with `generate_release_notes: true` + +**Rationale**: +- GitHub's built-in release notes are sufficient +- Groups commits by type automatically +- No need for CHANGELOG.md maintenance +- Can be customized via `.github/release.yml` if needed later + +## No Further Clarifications Needed + +All technical decisions resolved. Ready for implementation. diff --git a/specs/011-release-automation/spec.md b/specs/011-release-automation/spec.md new file mode 100644 index 0000000..ed62881 --- /dev/null +++ b/specs/011-release-automation/spec.md @@ -0,0 +1,115 @@ +# Feature Specification: Release Automation + +**Feature Branch**: `011-release-automation` +**Created**: 2025-11-28 +**Status**: Draft +**Input**: GitHub Issue #88 - Release policy / mechanism + +## Overview + +Establish a formal release process with CI/CD automation for consistent semantic versioning (vX.Y.Z) releases. Releases are triggered by pushing a version tag (e.g., `v0.1.5`) to the main branch. Modeled after sister project (GramFrame) release documentation and workflows. + +## Clarifications + +### Session 2025-11-28 + +- Q: How should releases be triggered? → A: Tag-triggered - pushing a `vX.Y.Z` tag to main branch triggers the release workflow + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - Trigger a New Release (Priority: P1) + +A maintainer wants to create a new versioned release of the project. They push a version tag (e.g., `v0.1.5`) to the main branch, and the system automatically builds, validates, and publishes a GitHub Release with artifacts. + +**Why this priority**: Core value of the feature - automated releases reduce human error and friction. + +**Independent Test**: Can be tested by pushing a `vX.Y.Z` tag to main and verifying a new GitHub Release is created with correct version and artifacts. + +**Acceptance Scenarios**: + +1. **Given** the main branch has commits, **When** a maintainer pushes a tag `v0.1.5`, **Then** a new GitHub Release `v0.1.5` is created +2. **Given** a release is triggered by tag, **When** the workflow completes, **Then** the release includes the built bundle artifact (sonar-quiz.iife.js) +3. **Given** a release is triggered by tag, **When** the workflow completes, **Then** the release notes summarize changes since the previous tag + +--- + +### User Story 2 - View Release Documentation (Priority: P2) + +A contributor or maintainer wants to understand the release process, versioning strategy, and how to create releases. They can find clear documentation that explains the policy. + +**Why this priority**: Documentation enables self-service and reduces onboarding friction. + +**Independent Test**: Can be tested by reviewing that RELEASE.md exists and contains complete instructions. + +**Acceptance Scenarios**: + +1. **Given** a new contributor, **When** they read RELEASE.md, **Then** they understand how versioning works +2. **Given** a maintainer, **When** they read RELEASE.md, **Then** they know how to create a release via tagging + +--- + +### User Story 3 - Package.json Version Sync (Priority: P3) + +The system keeps package.json version in sync with the git tag used for the release. + +**Why this priority**: Version consistency is important but the git tag is the source of truth. + +**Independent Test**: Can be tested by checking that package.json version matches the release tag after workflow completes. + +**Acceptance Scenarios**: + +1. **Given** a tag `v0.1.5` is pushed, **When** release workflow runs, **Then** package.json version is updated to `0.1.5` +2. **Given** package.json has version `0.1.0`, **When** tag `v0.2.0` triggers release, **Then** package.json is updated and committed + +--- + +### Edge Cases + +- What happens when tag format is invalid (not vX.Y.Z)? (Workflow ignores non-matching tags) +- What happens when CI checks fail after tag push? (Release is not created, tag remains, error reported) +- What happens when package.json update fails? (Release continues, warning issued - tag is source of truth) + +## Requirements *(mandatory)* + +### Functional Requirements + +- **FR-001**: System MUST provide a GitHub Actions workflow triggered by `vX.Y.Z` tags on main branch +- **FR-002**: System MUST generate release artifacts including the production bundle (dist/sonar-quiz.iife.js) +- **FR-003**: System MUST create GitHub Release with the same version as the pushed tag +- **FR-004**: System MUST update package.json version to match the tag version +- **FR-005**: System MUST generate release notes from commit history since previous tag +- **FR-006**: System MUST validate that all CI checks pass before creating a release +- **FR-007**: System MUST document the release process in RELEASE.md +- **FR-008**: Releases MUST include source code archives (zip, tar.gz - GitHub default) +- **FR-009**: System MUST attach the built bundle as a downloadable release asset +- **FR-010**: System MUST ignore tags that don't match the `vX.Y.Z` pattern + +### Key Entities + +- **Release**: A versioned snapshot with version tag, changelog, and artifacts +- **Version Tag**: Git tag in format `vX.Y.Z` that triggers the release workflow +- **Release Asset**: Built bundle file attached to GitHub Release for download + +## Success Criteria *(mandatory)* + +### Measurable Outcomes + +- **SC-001**: A new release is created within 5 minutes of pushing a valid version tag +- **SC-002**: 100% of releases include the production bundle artifact +- **SC-003**: Release documentation is comprehensive enough for any maintainer to create a release without external guidance +- **SC-004**: Package.json version matches git tag version after release +- **SC-005**: All releases pass CI validation before publishing + +## Assumptions + +- Maintainers will push tags in valid `vX.Y.Z` format +- GitHub Actions is the CI/CD platform (already in use for PR previews and pages deployment) +- The existing npm build process produces valid production bundles +- Maintainers have appropriate GitHub permissions to push tags and create releases + +## Out of Scope + +- NPM package publishing (project is not an npm package for distribution) +- CDN deployment (offline-first architecture) +- Automatic version inference from commits (version is explicit in tag) +- Pre-release/beta versioning (can be added later if needed) diff --git a/specs/011-release-automation/tasks.md b/specs/011-release-automation/tasks.md new file mode 100644 index 0000000..d9cb524 --- /dev/null +++ b/specs/011-release-automation/tasks.md @@ -0,0 +1,165 @@ +# Tasks: Release Automation + +**Input**: Design documents from `/specs/011-release-automation/` +**Prerequisites**: plan.md (required), spec.md (required), research.md + +**Tests**: Not applicable - CI/CD infrastructure is validated through tag push and release verification + +**Organization**: Tasks grouped by user story for independent implementation + +## Format: `[ID] [P?] [Story] Description` + +- **[P]**: Can run in parallel (different files, no dependencies) +- **[Story]**: Which user story this task belongs to (US1, US2, US3) +- Include exact file paths in descriptions + +--- + +## Phase 1: Setup (Shared Infrastructure) + +**Purpose**: No setup required - project already has GitHub Actions infrastructure + +- [x] T001 Verify existing CI workflow structure in .github/workflows/ci.yml + +**Checkpoint**: Existing infrastructure confirmed + +--- + +## Phase 2: Foundational (Blocking Prerequisites) + +**Purpose**: No foundational work needed - this feature adds new workflow, doesn't modify existing + +**⚠️ Note**: This feature is additive - no blocking prerequisites + +**Checkpoint**: Ready to begin user stories + +--- + +## Phase 3: User Story 1 - Trigger a New Release (Priority: P1) 🎯 MVP + +**Goal**: Pushing a `vX.Y.Z` tag to main triggers workflow that creates GitHub Release with bundle artifacts + +**Independent Test**: Push tag `v0.1.5` to main, verify GitHub Release created with correct version and attached sonar-quiz.iife.js + +### Implementation for User Story 1 + +- [x] T002 [US1] Create release workflow file with tag push trigger (v[0-9]+.[0-9]+.[0-9]+) in .github/workflows/release.yml +- [x] T003 [US1] Add CI validation jobs (lint, test, build) reusing patterns from ci.yml in .github/workflows/release.yml +- [x] T004 [US1] Add version extraction step from GITHUB_REF_NAME in .github/workflows/release.yml +- [x] T005 [US1] Add GitHub Release creation using softprops/action-gh-release in .github/workflows/release.yml +- [x] T006 [US1] Configure release notes auto-generation from commits in .github/workflows/release.yml +- [x] T007 [US1] Configure artifact upload (sonar-quiz.iife.js, source map) as release assets in .github/workflows/release.yml +- [x] T008 [US1] Add permissions block for contents:write in .github/workflows/release.yml + +**Checkpoint**: Release workflow functional - tag push creates release with artifacts + +--- + +## Phase 4: User Story 2 - View Release Documentation (Priority: P2) + +**Goal**: Contributors can find clear documentation explaining release process via tagging + +**Independent Test**: Read docs/RELEASE.md and verify it contains complete tagging instructions + +### Implementation for User Story 2 + +- [x] T009 [P] [US2] Create RELEASE.md with overview section explaining semantic versioning in docs/RELEASE.md +- [x] T010 [P] [US2] Add "How to Create a Release" section with git tag commands in docs/RELEASE.md +- [x] T011 [US2] Add version format requirements (vX.Y.Z pattern) in docs/RELEASE.md +- [x] T012 [US2] Add troubleshooting section for common issues in docs/RELEASE.md + +**Checkpoint**: Documentation complete - any maintainer can self-service release process + +--- + +## Phase 5: User Story 3 - Package.json Version Sync (Priority: P3) + +**Goal**: Package.json version is updated to match the git tag after release + +**Independent Test**: Push tag v0.2.0, verify package.json version updated to 0.2.0 on main branch + +### Implementation for User Story 3 + +- [x] T013 [US3] Add package.json version update step extracting version from tag in .github/workflows/release.yml +- [x] T014 [US3] Add git commit for version update with message "chore(release): vX.Y.Z" in .github/workflows/release.yml +- [x] T015 [US3] Add git push to main branch for version commit in .github/workflows/release.yml +- [x] T016 [US3] Handle edge case: skip version commit if package.json already matches tag in .github/workflows/release.yml + +**Checkpoint**: Package.json stays in sync with release tags + +--- + +## Phase 6: Polish & Cross-Cutting Concerns + +**Purpose**: Edge cases and final validation + +- [x] T017 Update README.md with release process reference and link to docs/RELEASE.md +- [x] T018 Test by pushing test tag on feature branch to validate workflow syntax before merge + +--- + +## Dependencies & Execution Order + +### Phase Dependencies + +- **Setup (Phase 1)**: Verification only - no changes +- **Foundational (Phase 2)**: N/A - additive feature +- **User Story 1 (Phase 3)**: Core workflow - MVP +- **User Story 2 (Phase 4)**: Documentation - independent of US1 +- **User Story 3 (Phase 5)**: Enhances US1 - depends on workflow existing +- **Polish (Phase 6)**: Depends on US1 complete + +### User Story Dependencies + +- **User Story 1 (P1)**: No dependencies - can start immediately +- **User Story 2 (P2)**: No dependencies - can start in parallel with US1 +- **User Story 3 (P3)**: Depends on US1 (workflow must exist to add version sync) + +### Parallel Opportunities + +- US1 and US2 can be implemented in parallel (different files) +- T009 and T010 within US2 can run in parallel + +--- + +## Parallel Example: User Stories 1 & 2 + +```bash +# These can run simultaneously: +Agent A: "Create release workflow in .github/workflows/release.yml" (US1) +Agent B: "Create RELEASE.md documentation in docs/RELEASE.md" (US2) +``` + +--- + +## Implementation Strategy + +### MVP First (User Story 1 Only) + +1. Complete T001 (verify existing) +2. Complete T002-T008 (core workflow) +3. **STOP and VALIDATE**: Push test tag, verify release created +4. Merge and test on main branch + +### Incremental Delivery + +1. US1 → Working tag-triggered releases +2. US2 → Documentation for team self-service +3. US3 → Package.json version sync + +### Suggested Execution Order + +Single developer: +1. T001 → T002-T008 (MVP workflow) +2. T009-T012 (documentation in parallel-friendly commits) +3. T013-T016 (version sync) +4. T017-T018 (polish) + +--- + +## Notes + +- All workflow tasks in US1 affect same file - execute sequentially +- Documentation tasks (US2) can be committed independently +- Test by pushing tag after workflow is merged to main +- No unit tests - infrastructure validated through actual tag push