diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 519e8e7..04044bb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,7 +20,6 @@ updates: - "black*" - "bandit*" - "safety*" - - "detect-secrets*" - "taskipy*" - "pdoc*" - "hypothesis*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 031f350..1a35e51 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,19 +53,6 @@ jobs: - name: Run type checking run: uv run python -c "import taskipy.cli; taskipy.cli.main()" static-check - - - name: Check for secrets - shell: bash - run: | - # SECURITY: Fail on errors, undefined variables, pipe failures - set -euo pipefail - if [[ ! -f .secrets.baseline ]]; then - echo "Creating secrets baseline..." - uv run detect-secrets scan --baseline .secrets.baseline - fi - # Check for new secrets since baseline - uv run detect-secrets scan --baseline .secrets.baseline - echo "✅ Secret scanning complete - no new secrets detected" test: name: Tests @@ -191,7 +178,6 @@ jobs: echo "Security rules (S001-S701) checked during linting phase." >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Additional Security Features" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Secret scanning (detect-secrets)" >> $GITHUB_STEP_SUMMARY echo "- ✅ Dependency vulnerability scanning (safety + dependabot)" >> $GITHUB_STEP_SUMMARY echo "- ✅ CodeQL security analysis (weekly + on pushes)" >> $GITHUB_STEP_SUMMARY echo "- ✅ Comprehensive security rules via Ruff (flake8-bandit S001-S701)" >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/.opencode/agents/repo-manager.md b/.opencode/agents/repo-manager.md index 06b9931..26d460e 100644 --- a/.opencode/agents/repo-manager.md +++ b/.opencode/agents/repo-manager.md @@ -3,8 +3,8 @@ description: Release Engineer managing Git workflows, pull requests, and hybrid mode: subagent temperature: 0.3 tools: - write: false - edit: false + write: true + edit: true read: true grep: true glob: true @@ -106,37 +106,70 @@ Follow conventional commits: ## Release Management ### Release Process -1. **Prepare Release Branch** +1. **Analyze Since Last Release** ```bash - git checkout develop - git pull origin develop - git checkout -b release/v{major}.{minor}.{YYYYMMDD} + last_tag=$(git describe --tags --abbrev=0) + git log ${last_tag}..HEAD --oneline + gh pr list --state merged --limit 20 --json title,number,labels ``` -2. **Analyze PR Sentiment** - - Use `gh pr list --state merged --base develop` - - Analyze PR titles/descriptions for themes - - Generate appropriate adjective-animal name +2. **Generate Release Name and Body** + Based on commit/PR analysis: + - Identify dominant theme (features, cleanup, fixes, refactoring) + - Select unique adjective-animal pair not used before + - Write poetic tagline + - Explain why this name fits -3. **Update Version** +3. **Update Version and Changelog** - Update `pyproject.toml` version field - - Update `CHANGELOG.md` with PR summaries + - Add entry to `CHANGELOG.md` at top (after title header) - Commit version bump -4. **Create Release** - ```bash - git checkout main - git merge release/v{version} - git tag v{version} - git push origin main --tags - gh release create v{version} --title "{adjective} {animal}" --notes-from-tag +4. **Create Beautiful GitHub Release** + The release notes MUST follow this exact format: + ```markdown + # Release v{version} - {Adjective Animal} {emoji} + + > *"{poetic tagline}"* + + ## Changelog + + ### Features + - feat: description (#PR) + + ### Bug Fixes + - fix: description (#PR) + + ### Refactoring + - refactor: description (#PR) + + ### Documentation + - docs: description (#PR) + + ### Merges + - Merge pull request #XX from branch + + ## Summary + + 2-3 sentence summary of what this release accomplishes. + + --- + **SHA**: `{short_sha}` ``` -5. **Sync Develop** +5. **Execute Release** ```bash - git checkout develop - git merge main - git push origin develop + # Create and push tag + git tag -a v{version} -m "Release v{version} - {Adjective Animal}" + git push origin v{version} + + # Create GitHub release with formatted notes + gh release create v{version} \ + --title "Release v{version} - {Adjective Animal}" \ + --notes "$(cat <<'EOF' + {formatted release notes as shown above} + EOF + )" ``` ## Available Skills diff --git a/.opencode/skills/git-release/SKILL.md b/.opencode/skills/git-release/SKILL.md index d73bf57..94b117c 100644 --- a/.opencode/skills/git-release/SKILL.md +++ b/.opencode/skills/git-release/SKILL.md @@ -8,7 +8,7 @@ metadata: workflow: release-management --- ## What I do -Manage the complete release process including version calculation, changelog generation, release creation, and themed naming based on PR sentiment analysis. +Manage the complete release process including version calculation, changelog generation, release creation, and themed naming based on commit/PR content analysis. Produces beautifully formatted GitHub releases. ## When to use me Use this when ready to create a new release after features are complete and tested. @@ -23,20 +23,12 @@ Use this when ready to create a new release after features are complete and test - **Minor**: New features, significant enhancements, or same-day releases - **Date**: Release date in YYYYMMDD format -**Examples:** -``` -v1.0.20260302 # Version 1.0, release on March 2, 2026 -v1.1.20260315 # Version 1.1, release on March 15, 2026 -v1.2.20260315 # Version 1.2, second release same day -v2.0.20260401 # Version 2.0, breaking changes on April 1, 2026 -``` - ### Version Bump Rules ```bash # Feature release (minor bump) v1.2.20260302 → v1.3.{today} -# Breaking change (major bump) +# Breaking change (major bump) v1.2.20260302 → v2.0.{today} # Same day release (increment minor by 2) @@ -47,261 +39,190 @@ v1.2.20260302 → v1.3.20260302 ### AI-Generated Themed Naming -The release name is generated by the AI based on analyzing the merged PRs and their content. The AI should: - -1. **Analyze PR content** - Read titles, descriptions, and code changes -2. **Identify dominant theme** - What is this release really about? -3. **Generate unique name** - Create an adjective-animal pair that: - - Reflects the PR content accurately - - Has not been used before in this project - - Is memorable and appropriate +The release name is generated by analyzing the merged PRs and commits since the last release. Generate a unique adjective-animal pair that: +- Reflects the PR/commit content accurately +- Has not been used before in this project +- Is memorable and appropriate ### Guidelines for AI **Good adjectives** (avoid generic ones): -- Emotional/sensory: `electric`, `radiant`, `fiery`, `velvet`, `crystalline` +- Emotional/sensory: `electric`, `radiant`, `fiery`, `velvet`, `crystalline`, `luminous` - Movement: `surging`, `drifting`, `soaring`, `diving`, `spiral` - Nature: `blooming`, `misty`, `aurora`, `tidal`, `verdant` -- Abstract: `boundless`, `infinite`, `hidden`, `silent`, `luminous` +- Abstract: `boundless`, `infinite`, `hidden`, `silent` **Good animals** (avoid overused ones like fox, owl, dolphin, cheetah): -- Exotic: `narwhal`, `axolotl`, `capybara`, `quokka`, `pangolin` -- Aquatic: `jellyfish`, `seahorse`, `manta`, `cuttlefish`, `otter` -- Birds: `kingfisher`, `heron`, `ibis`, `stork`, `bird-of-paradise` +- Exotic: `narwhal`, `axolotl`, `capybara`, `quokka`, `pangolin`, `kestrel` +- Aquatic: `jellyfish`, `seahorse`, `manta`, `cuttlefish`, `otter`, `gecko` +- Birds: `kingfisher`, `heron`, `ibis`, `stork`, `bird-of-paradise`, `kestrel` - Insects: `firefly`, `butterfly`, `dragonfly`, `beetle`, `mantid` - Mythical-inspired: `phoenix`, `griffin`, `pegasus`, `siren`, `chimera` -**Avoid repetition** - Check previous releases and choose something new. - -### Examples - -Instead of pre-defined categories, the AI decides: -``` -v1.2.20260315 - Blooming Narwhal (based on new features, growth theme) -v1.3.20260316 - Velvet Manta (based on smooth refactoring) -v1.4.20260317 - Electric Firefly (based on performance improvements) -v1.5.20260403 - Crystal Jellyfish (based on documentation overhaul) +**Avoid repetition** - Check previous releases: +```bash +git tag -l --sort=-v:refname | head -10 ``` -## PR Analysis for Release Naming +## Release Process Workflow -### AI Analysis Process +### Step 1: Analyze Commits Since Last Release +```bash +# Get last tag +last_tag=$(git describe --tags --abbrev=0) -Instead of rigid keyword matching, the AI should: +# Get commits since last release +git log ${last_tag}..HEAD --oneline -1. **Gather Recent PRs** - ```bash - gh pr list --state merged --base main --limit 20 --json title,body,labels - ``` +# Get merged PRs +gh pr list --state merged --limit 20 --json title,number,labels +``` -2. **Understand the content** - Read PR titles and descriptions to understand what changed +### Step 2: Generate Release Name and Body -3. **Identify the story** - What's the narrative of this release? What stands out? +**AI Analysis Process:** -4. **Generate creative name** - Based on understanding, create a unique adjective-animal pair +1. Read all commits and PRs since last release +2. Categorize changes: Features, Bug Fixes, Refactoring, Documentation, etc. +3. Identify dominant theme/vibe +4. Select adjective-animal pair that captures the essence +5. Write a brief explanation of why that name fits -**Remember:** -- Each release should have a unique name - don't repeat -- The name should feel authentic and memorable -- Let the PR content guide the naming, not the other way around +### Step 3: Create Beautiful GitHub Release -## Release Process Workflow +The release body MUST follow this exact format: -### Step 1: Prepare Release -```bash -# Ensure clean state -git checkout develop -git pull origin develop +```markdown +# Release {version} - {animal_name} {emoji} -# Check for unreleased changes -git log --oneline $(git describe --tags --abbrev=0)..HEAD +> *"{poetic tagline}"* -# Create release branch -current_date=$(date +%Y%m%d) -git checkout -b release/v1.3.${current_date} -``` +## Changelog -### Step 2: Analyze PRs and Generate Name -```bash -# Get merged PRs since last release -last_tag=$(git describe --tags --abbrev=0) -gh pr list --state merged --base develop --limit 20 - -# Use YOUR AI to analyze the PR titles and descriptions: -# - Read each PR title and description -# - Understand what the changes are actually about -# - Determine the dominant theme/vibe -# - Select an appropriate adjective-animal pair - -# Example (you must do real analysis): -# Recent PRs: -# - "Add session-workflow skill for multi-session AI development" -# - "Remove BDD references and DEVELOPMENT_WORKFLOW.md" -# - "Template hotfix - Jinja2 escaping" -# -# AI Analysis: These are primarily about FEATURES and IMPROVEMENTS -# The addition of a new skill is the dominant theme -# Selected name: "creative fox" (features theme) -``` +### Features +- feat: description (#PR) -### Step 3: Update Version and Changelog -```bash -# Update pyproject.toml -sed -i 's/version = ".*"/version = "1.3.20260302"/' pyproject.toml +### Bug Fixes +- fix: description (#PR) -# Generate changelog entry -cat >> CHANGELOG.md << EOF -## [v1.3.20260302] - Swift Cheetah - 2026-03-02 +### Refactoring +- refactor: description (#PR) -### Performance Improvements -- Optimize database query performance (#123) -- Add caching layer for API responses (#124) -- Improve search algorithm efficiency (#125) -- Speed up test suite execution (#126) +### Documentation +- docs: description (#PR) -### Migration Notes -- No breaking changes in this release -- Cache configuration is optional but recommended +### Merges +- Merge pull request #XX from branch -EOF +## Summary -# Commit version bump -git add pyproject.toml CHANGELOG.md -git commit -m "chore(release): bump version to v1.3.20260302 - Swift Cheetah" -``` +2-3 sentence summary of what this release accomplishes. -### Step 4: Create and Publish Release -```bash -# Merge to main -git checkout main -git merge release/v1.3.20260302 +--- +**SHA**: `{short_sha}` +``` -# Create tag -git tag v1.3.20260302 +### Example Release (v2.1.20260413): +```markdown +# Release v2.1.20260413 - Polished Gecko 🦎 -# Push to remote -git push origin main --tags +> *"Like a gecko scaling a wall, this release polishes and adheres to better practices"* -# Create GitHub release -gh release create v1.3.20260302 \ - --title "v1.3.20260302 - Swift Cheetah" \ - --notes-file CHANGELOG.md +## Changelog -# Sync develop branch -git checkout develop -git merge main -git push origin develop +### Bug Fixes +- fix: remove custom CodeQL workflow to resolve config conflict +- fix: reduce complexity in run function to pass CI checks -# Clean up release branch -git branch -d release/v1.3.20260302 -git push origin --delete release/v1.3.20260302 -``` +### Features +- feat: add workflow coordination skills and enhanced QA enforcement -### Step 5: Post-Release Tasks -```bash -# Verify release -gh release view v1.3.20260302 +## Summary -# Check CI/CD pipeline -gh workflow run deploy --ref v1.3.20260302 +This release focuses on **polishing** the template with Docker cleanup, +CI compliance fixes, and enhanced QA enforcement skills. -# Update project documentation -echo "Latest release: v1.3.20260302 - Swift Cheetah" > .release-info +--- +** SHA**: `80be795` ``` -## Hotfix Release Process +## Step-by-Step Release Process -### Emergency Fixes (Same Day) +### 1. Analyze and Generate ```bash -# Create hotfix from main -git checkout main -git checkout -b hotfix/critical-security-fix +# Get commits since last release +last_tag=$(git describe --tags --abbrev=0) +commits=$(git log ${last_tag}..HEAD --oneline) -# Make minimal changes -git add . -git commit -m "fix(security): patch authentication vulnerability" +# Get PRs +gh pr list --state merged --limit 20 --json title,number,labels -# Create PR for review -gh pr create --title "Critical Security Hotfix" \ - --body "Emergency patch for authentication vulnerability" +# Analyze and determine name/theme +``` -# After merge, create minor release for same day +### 2. Update pyproject.toml +```bash +# Calculate new version current_date=$(date +%Y%m%d) -last_version=$(git describe --tags --abbrev=0) - -# Calculate next minor version (v1.3.20260302 → v1.4.20260302 if same day) -minor=$(echo $last_version | cut -d. -f2) -date_str=$(echo $last_version | cut -d. -f3) -new_minor=$((minor + 1)) -next_version="v${new_minor}.${date_str}" +# Increment minor or major as appropriate +sed -i "s/version = \".*\"/version = \"2.3.${current_date}\"/" pyproject.toml +``` -git tag $next_version -git push origin main --tags +### 3. Update CHANGELOG.md +Add entry at top in format: +```markdown +## [v{version}] - {adjective_animal} - {YYYY-MM-DD} -gh release create $next_version \ - --title "$next_version - Guardian Bear (Hotfix)" \ - --notes "Emergency security patch" +### Changed/Added/Fixed +- description ``` -## Integration with Quality Pipeline - -### Pre-Release Validation +### 4. Create GitHub Release ```bash -#!/bin/bash -# Release validation script +# Create the release with full formatted notes +gh release create v{version} \ + --title "Release v{version} - {Adjective Animal}" \ + --notes "$(cat <<'RELEASE_EOF' +# Release v{version} - {Adjective Animal} {emoji} -echo "🔍 Running pre-release validation..." +> *"{poetic tagline}"* -# Ensure all tests pass -task test || { echo "❌ Tests failed"; exit 1; } +## Changelog -# Verify linting -task lint || { echo "❌ Linting failed"; exit 1; } +{categorized changelog} -# Check type safety -task static-check || { echo "❌ Type checking failed"; exit 1; } +## Summary -# Validate version format -version=$(grep 'version =' pyproject.toml | cut -d'"' -f2) -if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]{8}$ ]]; then - echo "❌ Invalid version format: $version" - exit 1 -fi +{summary} -# Check changelog updated -if ! grep -q $version CHANGELOG.md; then - echo "❌ Version not found in CHANGELOG.md" - exit 1 -fi - -echo "✅ Pre-release validation passed!" +--- +**SHA**: `{short_sha}` +RELEASE_EOF +)" ``` -## Example Release Scenarios +## Hotfix Release Process -### Feature Release +For same-day emergency fixes: ```bash -# Scenario: Added user dashboard, API improvements, new export feature -# Analysis: 3 feature PRs, 1 performance PR -# Theme: FEATURES (dominant) -# Name: "innovative dolphin" -# Version: v1.4.20260315 +# Calculate minor increment +last_tag=$(git describe --tags --abbrev=0) +minor=$(echo $last_tag | cut -d. -f2) +date_str=$(date +%Y%m%d) +new_version="v$((minor + 1)).${date_str}" + +# Quick hotfix release +gh release create $new_version \ + --title "Release $new_version - {Animal} (Hotfix)" \ + --notes "Emergency patch for {issue}" ``` -### Security Release -```bash -# Scenario: Authentication fixes, permission updates, security audit -# Analysis: 4 security PRs, 1 docs PR -# Theme: SECURITY (dominant) -# Name: "vigilant owl" -# Version: v1.3.20260320 -``` +## Quality Checklist -### Major Release -```bash -# Scenario: API v2, removed legacy endpoints, new architecture -# Analysis: Breaking changes detected -# Theme: Based on supporting PRs -# Name: "pioneering eagle" -# Version: v2.0.20260401 -``` \ No newline at end of file +Before creating release, verify: +- [ ] All tests pass +- [ ] CHANGELOG.md updated with new version +- [ ] pyproject.toml version bumped +- [ ] Release name follows adjective-animal format +- [ ] Release notes follow the exact template format +- [ ] SHA reference included diff --git a/.opencode/templates/.github/dependabot.yml.template b/.opencode/templates/.github/dependabot.yml.template deleted file mode 100644 index ef29d37..0000000 --- a/.opencode/templates/.github/dependabot.yml.template +++ /dev/null @@ -1,50 +0,0 @@ -version: 2 -updates: - # Python dependencies - - package-ecosystem: "pip" - directory: "/" - schedule: - interval: "weekly" - day: "monday" - time: "09:00" - # Group updates to reduce PR noise - groups: - pytest: - patterns: - - "pytest*" - dev-tools: - patterns: - - "ruff" - - "pyright" - - "mutmut" - - "pdoc" - security: - patterns: - - "detect-secrets" - - "safety" - main-deps: - patterns: - - "fire" - - "dotenv" - # Security updates get higher priority - open-pull-requests-limit: 10 - reviewers: - - "ORIGINAL_GITHUB_USERNAME" - labels: - - "dependencies" - - "automated" - - # GitHub Actions updates - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - day: "monday" - time: "09:00" - open-pull-requests-limit: 5 - reviewers: - - "ORIGINAL_GITHUB_USERNAME" - labels: - - "github-actions" - - "dependencies" - - "automated" \ No newline at end of file diff --git a/.opencode/templates/.github/workflows/ci.yml.template b/.opencode/templates/.github/workflows/ci.yml.template deleted file mode 100644 index e933233..0000000 --- a/.opencode/templates/.github/workflows/ci.yml.template +++ /dev/null @@ -1,172 +0,0 @@ -name: CI - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -env: - # Improve pip performance - PIP_NO_CACHE_DIR: false - PIP_USER: 1 - # uv settings - UV_SYSTEM_PYTHON: 1 - UV_CACHE_DIR: /tmp/.uv-cache - -jobs: - quality: - name: Code Quality & Security - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v4 - with: - enable-cache: true - cache-dependency-glob: "uv.lock" - - - name: Set up Python 3.13 - run: uv python install 3.13 - - - name: Install dependencies - run: uv sync --locked --all-extras --dev - - - name: Run ruff linting (includes security checks) - run: uv run python -c "import taskipy.cli; taskipy.cli.main()" ruff-check - - - name: Check ruff formatting - run: uv run python -c "import taskipy.cli; taskipy.cli.main()" ruff-format --check - - - name: Run type checking - run: uv run python -c "import taskipy.cli; taskipy.cli.main()" static-check - - - name: Check for secrets - run: | - if [ ! -f .secrets.baseline ]; then - echo "Creating secrets baseline..." - uv run detect-secrets scan --baseline .secrets.baseline - fi - # Check for new secrets since baseline - uv run detect-secrets scan --baseline .secrets.baseline - echo "✅ Secret scanning complete - no new secrets detected" - - test: - name: Tests - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: ["3.12", "3.13"] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v4 - with: - enable-cache: true - cache-dependency-glob: "uv.lock" - python-version: ${{ matrix.python-version }} - - - name: Install dependencies - run: uv sync --locked --all-extras --dev - - - name: Run fast tests - run: uv run python -c "import taskipy.cli; taskipy.cli.main()" test-fast - - - name: Run full test suite (main branch and PRs only) - if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request' - run: uv run python -c "import taskipy.cli; taskipy.cli.main()" test - - - name: Upload coverage reports - if: matrix.python-version == '3.13' && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request') - uses: actions/upload-artifact@v4 - with: - name: coverage-reports - path: | - docs/coverage/ - docs/tests/ - retention-days: 30 - - - name: Upload coverage to Codecov (optional) - if: matrix.python-version == '3.13' && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request') - uses: codecov/codecov-action@v5 - with: - files: ./coverage.xml - fail_ci_if_error: false - verbose: true - - build: - name: Build & Documentation - runs-on: ubuntu-latest - needs: [quality, test] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v4 - with: - enable-cache: true - cache-dependency-glob: "uv.lock" - - - name: Set up Python 3.13 - run: uv python install 3.13 - - - name: Install dependencies - run: uv sync --locked --all-extras --dev - - - name: Build documentation - run: uv run python -c "import taskipy.cli; taskipy.cli.main()" doc-build - - - name: Build package - run: uv build - - - name: Verify package installation (wheel) - run: | - uv run --isolated --no-project --with dist/*.whl python -c "import app; print('✓ Wheel install successful')" - - - name: Verify package installation (sdist) - run: | - uv run --isolated --no-project --with dist/*.tar.gz python -c "import app; print('✓ Source dist install successful')" - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: python-package-distributions - path: dist/ - retention-days: 30 - - - name: Upload documentation - uses: actions/upload-artifact@v4 - with: - name: documentation - path: docs/api/ - retention-days: 30 - - # Security summary job - security-summary: - name: Security Summary - runs-on: ubuntu-latest - needs: [quality] - if: always() - - steps: - - name: Security Summary - run: | - echo "## 🔒 Security Scan Summary" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### ✅ Ruff Security Analysis" >> $GITHUB_STEP_SUMMARY - echo "Security rules (S001-S701) checked during linting phase." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Additional Security Features" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Secret scanning (detect-secrets)" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Dependency vulnerability scanning (safety + dependabot)" >> $GITHUB_STEP_SUMMARY - echo "- ✅ CodeQL security analysis (weekly + on pushes)" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Comprehensive security rules via Ruff (flake8-bandit S001-S701)" >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/.opencode/templates/.github/workflows/codeql.yml.template b/.opencode/templates/.github/workflows/codeql.yml.template deleted file mode 100644 index 3d548f1..0000000 --- a/.opencode/templates/.github/workflows/codeql.yml.template +++ /dev/null @@ -1,59 +0,0 @@ -name: "CodeQL Security Analysis" - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - schedule: - # Run CodeQL analysis weekly on Sundays at 6:00 AM UTC - - cron: '0 6 * * 0' - -jobs: - analyze: - name: Analyze Code - runs-on: ubuntu-latest - timeout-minutes: 360 - permissions: - # Required for all workflows - security-events: write - # Required for workflows in public repositories - actions: read - contents: read - - strategy: - fail-fast: false - matrix: - include: - - language: python - build-mode: none # CodeQL supports 'none' for Python (interpreted language) - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # Specify additional queries to run - queries: +security-and-quality - - # For Python, no build step is required as CodeQL analyzes source code directly - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" - - - name: Upload CodeQL results summary - run: | - echo "## 🔍 CodeQL Security Analysis Complete" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Analysis Details" >> $GITHUB_STEP_SUMMARY - echo "- **Language**: ${{ matrix.language }}" >> $GITHUB_STEP_SUMMARY - echo "- **Build Mode**: ${{ matrix.build-mode }}" >> $GITHUB_STEP_SUMMARY - echo "- **Queries**: security-and-quality" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Results are available in the Security tab of this repository." >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/.opencode/templates/.github/workflows/dependency-review.yml.template b/.opencode/templates/.github/workflows/dependency-review.yml.template deleted file mode 100644 index 62d3351..0000000 --- a/.opencode/templates/.github/workflows/dependency-review.yml.template +++ /dev/null @@ -1,24 +0,0 @@ -name: 'Dependency Review' -on: [pull_request] - -permissions: - contents: read - -jobs: - dependency-review: - runs-on: ubuntu-latest - steps: - - name: 'Checkout Repository' - uses: actions/checkout@v4 - - - name: 'Dependency Review' - uses: actions/dependency-review-action@v4 - with: - # Fail if any vulnerabilities are found - fail-on-severity: moderate - # Allow certain licenses (common permissive licenses) - allow-licenses: GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, MIT, BSD-2-Clause, BSD-3-Clause, ISC, Apache-2.0, Unlicense, 0BSD - # Deny problematic licenses - deny-licenses: AGPL-1.0, AGPL-3.0, GPL-1.0 - # Comment on PR with results - comment-summary-in-pr: always \ No newline at end of file diff --git a/.opencode/templates/.secrets.baseline.template b/.opencode/templates/.secrets.baseline.template deleted file mode 100644 index 3ecd45c..0000000 --- a/.opencode/templates/.secrets.baseline.template +++ /dev/null @@ -1,115 +0,0 @@ -{ - "version": "1.5.0", - "plugins_used": [ - { - "name": "ArtifactoryDetector" - }, - { - "name": "AWSKeyDetector" - }, - { - "name": "AzureStorageKeyDetector" - }, - { - "name": "Base64HighEntropyString", - "limit": 4.5 - }, - { - "name": "BasicAuthDetector" - }, - { - "name": "CloudantDetector" - }, - { - "name": "DiscordBotTokenDetector" - }, - { - "name": "GitHubTokenDetector" - }, - { - "name": "HexHighEntropyString", - "limit": 3.0 - }, - { - "name": "IbmCloudIamDetector" - }, - { - "name": "IbmCosHmacDetector" - }, - { - "name": "JwtTokenDetector" - }, - { - "name": "KeywordDetector", - "keyword_exclude": "" - }, - { - "name": "MailchimpDetector" - }, - { - "name": "NpmDetector" - }, - { - "name": "PrivateKeyDetector" - }, - { - "name": "SendGridDetector" - }, - { - "name": "SlackDetector" - }, - { - "name": "SoftlayerDetector" - }, - { - "name": "SquareOAuthDetector" - }, - { - "name": "StripeDetector" - }, - { - "name": "TwilioKeyDetector" - } - ], - "filters_used": [ - { - "path": "detect_secrets.filters.allowlist.is_line_allowlisted" - }, - { - "path": "detect_secrets.filters.common.is_baseline_file" - }, - { - "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", - "min_level": 2 - }, - { - "path": "detect_secrets.filters.heuristic.is_indirect_reference" - }, - { - "path": "detect_secrets.filters.heuristic.is_likely_id_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_lock_file" - }, - { - "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_potential_uuid" - }, - { - "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" - }, - { - "path": "detect_secrets.filters.heuristic.is_sequential_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_swagger_file" - }, - { - "path": "detect_secrets.filters.heuristic.is_templated_secret" - } - ], - "results": {}, - "generated_at": "2026-04-11T17:00:00Z" -} \ No newline at end of file diff --git a/.opencode/templates/CHANGELOG.md.template b/.opencode/templates/CHANGELOG.md.template deleted file mode 100644 index f1775dd..0000000 --- a/.opencode/templates/CHANGELOG.md.template +++ /dev/null @@ -1,61 +0,0 @@ -# Changelog - -All notable changes to this template will be documented in this file. - -## [v1.7.20260410] - Vivid Cardinal - 2026-04-10 - -### Added -- **QA-gated Epic Workflow** - Complete epic-based development with mandatory quality checkpoints at each phase -- **Epic-workflow Skill** - Manages epic-based development with automatic feature progression -- **EPICS.md Template** - Epic tracking and management file for generated projects - -### Changed -- Updated all agent descriptions to use industry-standard roles (Development Lead, Software Architect, QA Specialist, Business Analyst, Release Engineer) -- Removed model specifications from all agents to make template model-agnostic -- Updated AGENTS.md to properly document all 5 generated project agents and all skills -- Updated README.md with new workflow and agent roles - -### Fixed -- Documentation now accurately reflects what exists in template - -## [v1.6.20260409] - Guardian Owl - 2026-04-09 - -### Added -- **Overseer Agent** - Quality assurance agent that reviews work after each test implementation and requests changes if needed -- **Requirements Gatherer Agent** - Agent that asks questions to understand project needs, updates documentation, creates detailed analysis for architect - -### Changed -- Updated developer workflow to include `@overseer` calls after Phase 3 (TDD tests) and Phase 7 (Quality Assurance) -- Updated AGENTS.md with new agents and updated workflow examples - -## [v1.0.0] - 2026-03-12 - -### Added -- **AI-Enhanced Development Workflow** - Complete OpenCode integration for AI-powered development -- **Developer Agent** - Main development agent with 7-phase TDD workflow -- **Architect Agent** - Design review agent for SOLID principles and object calisthenics compliance -- **Repository Manager Agent** - Git operations, PRs, and themed releases management -- **Development Skills** - feature-definition, prototype-script, tdd, signature-design, implementation, code-quality -- **Repository Skills** - git-release (hybrid calver versioning with themed releases), pr-management -- **Meta Skills** - create-skill, create-agent for extending OpenCode -- **Template Management** - template-manager agent, template-test, template-release skills -- **Comprehensive CI Workflow** - Template validation, generated project tests, Docker builds -- **Validation Scripts** - cookiecutter.json, pyproject.toml, YAML frontmatter validation - -### Changed -- Updated README.md with modern AI-focused branding -- Updated generated project README template with AI development workflow - -### Features -- **7-Phase Development Cycle**: Feature Definition → Prototype → TDD → Signature Design → Architecture Review → Implementation → Quality Assurance -- **SOLID Principles Enforcement** - Single responsibility, dependency inversion, interface segregation -- **Object Calisthenics** - No primitives, small classes, behavior-rich objects -- **Hybrid Calver Versioning**: v1.2.20260302 format with themed releases -- **Themed Release Names**: "Swift Cheetah", "Vigilant Owl", "Creative Fox" based on PR sentiment -- **Property-Based Testing**: Hypothesis integration for robust test coverage - -### Migration Notes -- This is the first semantic version release -- No breaking changes to cookiecutter.json structure -- Generated projects now include OpenCode agents and skills -- Existing projects can regenerate to get new features diff --git a/.opencode/templates/TODO.md.template b/.opencode/templates/TODO.md.template deleted file mode 100644 index 7f63b19..0000000 --- a/.opencode/templates/TODO.md.template +++ /dev/null @@ -1,83 +0,0 @@ -# Python Project Template - Development TODO - -This file tracks current feature development. For full feature list, see docs/roadmap.md and docs/features/backlog/. -Each session should read TODO.md and docs/roadmap.md to understand current state. - -**Convention:** `[ ]` = pending, `[x]` = done, `[~]` = in progress, `[-]` = skipped - -> **For AI agents:** Use `/skill session-workflow` and `/skill epic-workflow` for proper workflow management. - ---- - -## Current Feature: Project Setup - -### Phase 0: Initial Setup -- [x] Project created via template -- [ ] Review and update `README.md` with project-specific description -- [ ] Install dependencies: `uv venv && uv pip install -e '.[dev]'` -- [ ] Verify base tests pass: `task test` -- [ ] Create first feature in docs/features/backlog/ - -### QA Checkpoint -- [ ] @overseer: Review project setup completeness -- [ ] QA Status: ⏸️ Pending - ---- - -## Feature Development Phases (Template) - -When starting a new feature, copy these phases: - -### Phase 1: Requirements Gathering -- [ ] @requirements-gatherer: Conduct stakeholder interview -- [ ] Create feature in docs/features/backlog/.md -- [ ] Define acceptance criteria -- [ ] QA: @overseer reviews requirements - -### Phase 2: Feature Definition -- [ ] @developer /skill feature-definition -- [ ] Document technical requirements -- [ ] Update docs/roadmap.md with feature details - -### Phase 3: Test Development -- [ ] @developer /skill prototype-script (if needed) -- [ ] @developer /skill tdd -- [ ] Write BDD-style tests with Given/When/Then -- [ ] QA: @overseer reviews test quality - -### Phase 4: Design & Architecture -- [ ] @developer /skill signature-design -- [ ] @architect: Review and approve design -- [ ] Address architectural feedback - -### Phase 5: Implementation -- [ ] @developer /skill implementation -- [ ] Implement using TDD (Red-Green-Refactor) -- [ ] QA: @overseer reviews SOLID/DRY/KISS compliance - -### Phase 6: Final Quality Assurance -- [ ] @developer /skill code-quality -- [ ] Run all quality checks (lint, type-check, test) -- [ ] QA: @overseer final approval - -### Phase 7: Feature Completion -- [ ] Move feature to docs/features/completed/ with metadata -- [ ] @developer /skill epic-workflow next-feature -- [ ] Proceed to next feature - ---- - -## Session Log - -| Date | Session Summary | -|------------|----------------------------------------------------| -| (date) | Project scaffolded via template, TODO created | - ---- - -## Notes for Next Session - -- Start with **Phase 1**: update `README.md` with project-specific content -- Then proceed to **Phase 2**: define the core features -- Run `task test` to verify the base template tests pass before making changes -- See `AGENTS.md` for project details and available commands diff --git a/.opencode/templates/project_defaults.json.template b/.opencode/templates/project_defaults.json.template deleted file mode 100644 index 1e16c33..0000000 --- a/.opencode/templates/project_defaults.json.template +++ /dev/null @@ -1,7 +0,0 @@ -{ - "github_username": "nullhack", - "project_name": "python-project-template", - "project_description": "Python template with some awesome tools to quickstart any Python project", - "author_name": "eol", - "author_email": "nullhack@users.noreply.github.com" -} \ No newline at end of file diff --git a/.opencode/templates/pyproject.toml.template b/.opencode/templates/pyproject.toml.template index f9bf6ee..9447540 100644 --- a/.opencode/templates/pyproject.toml.template +++ b/.opencode/templates/pyproject.toml.template @@ -166,6 +166,5 @@ static-check = "pyright" [dependency-groups] dev = [ - "detect-secrets>=1.5.0", "safety>=3.7.0", ] diff --git a/.secrets.baseline b/.secrets.baseline deleted file mode 100644 index ae3de15..0000000 --- a/.secrets.baseline +++ /dev/null @@ -1,137 +0,0 @@ -{ - "version": "1.5.0", - "plugins_used": [ - { - "name": "ArtifactoryDetector" - }, - { - "name": "AWSKeyDetector" - }, - { - "name": "AzureStorageKeyDetector" - }, - { - "name": "Base64HighEntropyString", - "limit": 4.5 - }, - { - "name": "BasicAuthDetector" - }, - { - "name": "CloudantDetector" - }, - { - "name": "DiscordBotTokenDetector" - }, - { - "name": "GitHubTokenDetector" - }, - { - "name": "GitLabTokenDetector" - }, - { - "name": "HexHighEntropyString", - "limit": 3.0 - }, - { - "name": "IbmCloudIamDetector" - }, - { - "name": "IbmCosHmacDetector" - }, - { - "name": "IPPublicDetector" - }, - { - "name": "JwtTokenDetector" - }, - { - "name": "KeywordDetector", - "keyword_exclude": "" - }, - { - "name": "MailchimpDetector" - }, - { - "name": "NpmDetector" - }, - { - "name": "OpenAIDetector" - }, - { - "name": "PrivateKeyDetector" - }, - { - "name": "PypiTokenDetector" - }, - { - "name": "SendGridDetector" - }, - { - "name": "SlackDetector" - }, - { - "name": "SoftlayerDetector" - }, - { - "name": "SquareOAuthDetector" - }, - { - "name": "StripeDetector" - }, - { - "name": "TelegramBotTokenDetector" - }, - { - "name": "TwilioKeyDetector" - } - ], - "filters_used": [ - { - "path": "detect_secrets.filters.allowlist.is_line_allowlisted" - }, - { - "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", - "min_level": 2 - }, - { - "path": "detect_secrets.filters.heuristic.is_indirect_reference" - }, - { - "path": "detect_secrets.filters.heuristic.is_likely_id_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_lock_file" - }, - { - "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_potential_uuid" - }, - { - "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" - }, - { - "path": "detect_secrets.filters.heuristic.is_sequential_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_swagger_file" - }, - { - "path": "detect_secrets.filters.heuristic.is_templated_secret" - } - ], - "results": { - ".opencode/skills/feature-definition/SKILL.md": [ - { - "type": "Secret Keyword", - "filename": ".opencode/skills/feature-definition/SKILL.md", - "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", - "is_verified": false, - "line_number": 78 - } - ] - }, - "generated_at": "2026-04-11T19:09:42Z" -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cf2905..f1588fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,35 @@ All notable changes to this template will be documented in this file. +## [v2.2.20260413] - Luminous Kestrel - 2026-04-13 + +### Added +- **Architecture-First Feature System** - New directory structure separating business and architecture features +- **Architectural Analysis Skill** - Systematic architecture documentation for each feature +- **8-Phase Development Cycle** - Expanded from 7-phase with dedicated Architecture Analysis phase + +### Changed +- **BDD → Acceptance Criteria** - Renamed gherkin-validation to acceptance-criteria-validation for accurate terminology +- **Consistency Updates** - Fixed phase numbering, cross-references, and documentation across all agents and skills +- **Epic-Workflow Refactor** - Converted from epic-based to feature-selection with architecture-first priority +- **Manager Agent** - Enhanced with test signature creation capabilities + +### Migration Notes +- No breaking changes in this release +- Projects can continue using existing workflow + +## [v2.1.20260413] - Polished Gecko - 2026-04-13 + +### Added +- Docker simplification and cleanup +- V2 Development Workflow with CI/CD fixes +- Template refactoring for generic app package +- Enhanced QA enforcement skills + +### Changed +- Complexity fixes for CI compliance +- CodeQL config conflict resolved + ## [v2.0.20260411] - Armored Pangolin - 2026-04-11 ### 🚀 MAJOR RELEASE - V1 → V2 Architecture Transition diff --git a/EPICS.md b/EPICS.md deleted file mode 100644 index 32552a8..0000000 --- a/EPICS.md +++ /dev/null @@ -1,62 +0,0 @@ -# Python Project Template - Epic Tracking - -This file tracks all epics and their features. Each feature goes through mandatory QA gates before proceeding to the next. - -**Status Legend**: ⏸️ Pending | 🔄 In Progress | ✅ Complete | ❌ Blocked - ---- - -## Epic: Project Foundation -**Status**: 🔄 In Progress -**Business Value**: Establish the core infrastructure and development workflows for the project - -### Features: -1. **Project Setup** - Status: ⏸️ Pending - - Acceptance Criteria: - - Development environment configured - - All dependencies installed and verified - - Base tests passing - - QA Status: Not Started - -2. **Development Workflow** - Status: ⏸️ Pending - - Acceptance Criteria: - - All agents and skills operational - - Epic/feature workflow established - - QA gates functioning - - QA Status: Not Started - ---- - -## Epic: [Your First Epic Name] -**Status**: ⏸️ Pending -**Business Value**: [Why this epic provides value to users/business] - -### Features: -1. **[Feature 1 Name]** - Status: ⏸️ Pending - - Acceptance Criteria: - - [Specific measurable criterion] - - [Another criterion] - - QA Status: Not Started - -2. **[Feature 2 Name]** - Status: ⏸️ Pending - - Acceptance Criteria: - - [Specific measurable criterion] - - [Another criterion] - - QA Status: Not Started - ---- - -## QA History - -| Date | Feature | Epic | QA Result | Reviewer | -|------|---------|------|-----------|----------| -| YYYY-MM-DD | Feature Name | Epic Name | Approved/Rejected | @overseer | - ---- - -## Notes - -- Each feature must pass all QA gates before marked complete -- Features automatically flow to the next upon completion -- Epics complete when all contained features are done -- Use `@developer /skill epic-workflow` to manage epic progression \ No newline at end of file diff --git a/project_defaults.json b/project_defaults.json index e2dff3f..1e16c33 100644 --- a/project_defaults.json +++ b/project_defaults.json @@ -3,5 +3,5 @@ "project_name": "python-project-template", "project_description": "Python template with some awesome tools to quickstart any Python project", "author_name": "eol", - "author_email": "[EMAIL]" + "author_email": "nullhack@users.noreply.github.com" } \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 230608c..0a8a753 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "test-project" -version = "0.1.20260413" +version = "2.2.20260413" description = "A test project" readme = "README.md" requires-python = ">=3.13" @@ -166,6 +166,5 @@ static-check = "pyright" [dependency-groups] dev = [ - "detect-secrets>=1.5.0", "safety>=3.7.0", ] diff --git a/uv.lock b/uv.lock index 8a0dcfc..870568f 100644 --- a/uv.lock +++ b/uv.lock @@ -262,19 +262,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/f1/00ce3bde3ca542d1acd8f8cfa38e446840945aa6363f9b74746394b14127/cryptography-46.0.7-cp38-abi3-win_amd64.whl", hash = "sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3", size = 3472985, upload-time = "2026-04-08T01:57:36.714Z" }, ] -[[package]] -name = "detect-secrets" -version = "1.5.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyyaml" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/67/382a863fff94eae5a0cf05542179169a1c49a4c8784a9480621e2066ca7d/detect_secrets-1.5.0.tar.gz", hash = "sha256:6bb46dcc553c10df51475641bb30fd69d25645cc12339e46c824c1e0c388898a", size = 97351, upload-time = "2024-05-06T17:46:19.721Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/5e/4f5fe4b89fde1dc3ed0eb51bd4ce4c0bca406246673d370ea2ad0c58d747/detect_secrets-1.5.0-py3-none-any.whl", hash = "sha256:e24e7b9b5a35048c313e983f76c4bd09dad89f045ff059e354f9943bf45aa060", size = 120341, upload-time = "2024-05-06T17:46:16.628Z" }, -] - [[package]] name = "dotenv" version = "0.9.9" @@ -1167,7 +1154,7 @@ wheels = [ [[package]] name = "test-project" -version = "0.1.20260413" +version = "2.2.20260413" source = { virtual = "." } dependencies = [ { name = "dotenv" }, @@ -1190,7 +1177,6 @@ dev = [ [package.dev-dependencies] dev = [ - { name = "detect-secrets" }, { name = "safety" }, ] @@ -1212,10 +1198,7 @@ requires-dist = [ provides-extras = ["dev"] [package.metadata.requires-dev] -dev = [ - { name = "detect-secrets", specifier = ">=1.5.0" }, - { name = "safety", specifier = ">=3.7.0" }, -] +dev = [{ name = "safety", specifier = ">=3.7.0" }] [[package]] name = "textual"