From ada4e8b038593727be68e94c4de0eaf2595eb41f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 02:33:00 +0200 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20prompts?= =?UTF-8?q?=20and=20templates=20for=20feature=20specification=20and=20impl?= =?UTF-8?q?ementation=20processes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/prompts/implement.prompt.md | 36 +++++ .github/prompts/plan.prompt.md | 36 ++++- .github/prompts/specify.prompt.md | 23 ++- .../scripts/powershell/create-new-feature.ps1 | 19 ++- .specify/templates/plan-template.md | 2 +- .specify/templates/spec-template.md | 76 +++++----- specs/002-merge-ci-yml/spec.md | 134 ++++++++++++++++++ 7 files changed, 278 insertions(+), 48 deletions(-) create mode 100644 specs/002-merge-ci-yml/spec.md diff --git a/.github/prompts/implement.prompt.md b/.github/prompts/implement.prompt.md index c3fb21ef..0351c1aa 100644 --- a/.github/prompts/implement.prompt.md +++ b/.github/prompts/implement.prompt.md @@ -55,4 +55,40 @@ $ARGUMENTS - Confirm the implementation follows the technical plan - Report final status with summary of completed work +8. Create or update Pull Request: + - **Target branch**: The PR must be against the default branch + - **PR status**: The PR must not be draft, it should be ready for review + - **Determine PR type and icon** based on the changes: + + | Type of change | Icon | Label | + |-|-|-| + | Docs | πŸ“– | Docs | + | Fix | πŸͺ² | Fix, Patch | + | Security fix | ⚠️ | Fix | + | Patch | 🩹 | Patch | + | Feature | πŸš€ | Minor | + | Breaking change | 🌟 | Major | + + - **PR title format**: ` [Type of change]: ` + - **PR description structure**: + * Start with a summary paragraph describing the key outcome and changes for user + * DO NOT add a title before the leading paragraph + * At the end of the PR paragraph, add a "- Fixes #" line to link the PR to the issue + * Follow with additional details answering Why, How, and What + * Avoid superfluous headers or sections + * We do not need details, we need to add what changes for the user of the code + - **Apply appropriate label(s)** based on the type of change + - **Link the PR** to the associated issue + +9. Update issue labels: + - Remove 'plan' label from the linked issue + - Add 'implement' label to the linked issue + +10. Update the constitution: + - Read the [Constitution](../../.specify/memory/constitution.md) file. + - Read the [constitution prompt](./constitution.prompt.md) for guidance on how to update the constitution. + - Update the constitution file with details on what has been implemented in this PR + - Document the functionality that was added or changed, remove the sections that are no longer relevant + - Ensure the constitution reflects the current state of the codebase + Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running `/tasks` first to regenerate the task list. diff --git a/.github/prompts/plan.prompt.md b/.github/prompts/plan.prompt.md index 37a3aec1..f84d02c3 100644 --- a/.github/prompts/plan.prompt.md +++ b/.github/prompts/plan.prompt.md @@ -40,6 +40,40 @@ Given the implementation details provided as an argument, do this: - Ensure all required artifacts were generated - Confirm no ERROR states in execution -6. Report results with branch name, file paths, and generated artifacts. +6. Commit and push the changes: + - Stage all generated artifacts and modified files + - Create a commit with a descriptive message summarizing the plan + - Push the branch (BRANCH) to remote + +7. Create or update a Pull Request: + - The PR must be against the default branch. + - The PR must be opened as a draft. + - Determine the PR type and icon based on the changes: + + | Type of change | Icon | Label | + |-|-|-| + | Docs | πŸ“– | Docs | + | Fix | πŸͺ² | Fix, Patch | + | Security fix | ⚠️ | Fix | + | Patch | 🩹 | Patch | + | Feature | πŸš€ | Minor | + | Breaking change | 🌟 | Major | + + - Create PR title: ` [Type of change]: ` + - Create PR description: + * Start with a summary paragraph describing the key outcome and changes for user + * DO NOT add a title before the leading paragraph + * At the end of the PR paragraph, add a "- Fixes #" line to link the PR to the issue + * Follow with additional details answering Why, How, and What + * Avoid superfluous headers or sections + * We do not need details, we need to add what changes for the user of the code + - Apply appropriate label(s) based on the type of change + - Link the PR to the associated issue + +8. Update issue labels: + - Remove 'specification' label from the linked issue + - Add 'plan' label to the linked issue + +9. Report results with branch name, PR URL, file paths, and generated artifacts. Use absolute paths with the repository root for all file operations to avoid path issues. diff --git a/.github/prompts/specify.prompt.md b/.github/prompts/specify.prompt.md index e0358104..aed6c171 100644 --- a/.github/prompts/specify.prompt.md +++ b/.github/prompts/specify.prompt.md @@ -14,10 +14,25 @@ The text the user typed after `/specify` in the triggering message **is** the fe Given that feature description, do this: -1. Run the script `.specify/scripts/powershell/create-new-feature.ps1 -Json "$ARGUMENTS"` from repo root and parse its JSON output for BRANCH_NAME and SPEC_FILE. All file paths must be absolute. +1. Analyze the feature description and generate a concise, descriptive branch name: + - Extract the core concept/action from the description (2-4 words maximum) + - Use kebab-case format (lowercase, hyphen-separated) + - Focus on the primary change or feature being implemented + - Examples: "user-authentication", "merge-workflows", "api-rate-limiting", "fix-memory-leak" +2. Run the script `.specify/scripts/powershell/create-new-feature.ps1 -Json "$ARGUMENTS" -BranchName ""` from repo root and parse its JSON output for BRANCH_NAME and SPEC_FILE. All file paths must be absolute. **IMPORTANT** You must only ever run this script once. The JSON is provided in the terminal as output - always refer to it to get the actual content you're looking for. -2. Load `.specify/templates/spec-template.md` to understand required sections. -3. Write the specification to SPEC_FILE using the template structure, replacing placeholders with concrete details derived from the feature description (arguments) while preserving section order and headings. -4. Report completion with branch name, spec file path, and readiness for the next phase. + **NOTE** The script will prepend an auto-incremented feature number (e.g., `003-`) to your branch name. +3. Load `.specify/templates/spec-template.md` to understand required sections. +4. Write the specification to SPEC_FILE using the template structure, replacing placeholders with concrete details derived from the feature description (arguments) while preserving section order and headings. +5. Create a GitHub issue for this feature with: + - Title: Format as ` [Type]: ` where: + - Icon: πŸ“– (Docs), πŸͺ² (Fix), ⚠️ (Security fix), 🩹 (Patch), πŸš€ (Feature/Minor), 🌟 (Breaking change/Major) + - Type: Docs, Fix, Patch, Feature, or Breaking change + - Feature name: Short description from the spec + - Body: The complete content of the SPEC_FILE (spec.md) + - Labels: + - `Specification` (always - indicates current phase) + - Type-based label: `Docs`, `Fix`, `Patch`, `Minor`, or `Major` based on the type of change +6. Report completion with branch name, spec file path, issue number, and readiness for the next phase. Note: The script creates and checks out the new branch and initializes the spec file before writing. diff --git a/.specify/scripts/powershell/create-new-feature.ps1 b/.specify/scripts/powershell/create-new-feature.ps1 index 6ff1c3db..6e8d717f 100644 --- a/.specify/scripts/powershell/create-new-feature.ps1 +++ b/.specify/scripts/powershell/create-new-feature.ps1 @@ -4,7 +4,9 @@ param( [switch]$Json, [Parameter(ValueFromRemainingArguments = $true)] - [string[]]$FeatureDescription + [string[]]$FeatureDescription, + [Parameter()] + [string]$BranchName ) $ErrorActionPreference = 'Stop' @@ -52,9 +54,18 @@ if (Test-Path $specsDir) { $next = $highest + 1 $featureNum = ('{0:000}' -f $next) -$branchName = $featureDesc.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' -$words = ($branchName -split '-') | Where-Object { $_ } | Select-Object -First 3 -$branchName = "$featureNum-$([string]::Join('-', $words))" +# Use provided BranchName if available, otherwise generate from feature description +if ($BranchName) { + # Sanitize the provided branch name + $branchSuffix = $BranchName.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' +} else { + # Fallback: Generate from feature description (first 3 words) + $branchSuffix = $featureDesc.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' + $words = ($branchSuffix -split '-') | Where-Object { $_ } | Select-Object -First 3 + $branchSuffix = [string]::Join('-', $words) +} + +$branchName = "$featureNum-$branchSuffix" if ($hasGit) { try { diff --git a/.specify/templates/plan-template.md b/.specify/templates/plan-template.md index 0fad4eb9..f2d4f9aa 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -267,4 +267,4 @@ directories captured above] - [ ] Complexity deviations documented --- -*Based on Constitution v1.3.0 - See `.specify/memory/constitution.md`* +*Based on Constitution - See `.specify/memory/constitution.md`* diff --git a/.specify/templates/spec-template.md b/.specify/templates/spec-template.md index c675f825..df60a7ea 100644 --- a/.specify/templates/spec-template.md +++ b/.specify/templates/spec-template.md @@ -1,5 +1,43 @@ # Feature Specification: [FEATURE NAME] +## User Scenarios & Testing *(mandatory)* + +### Primary User Story + +[Describe the main user journey in plain language] + +### Acceptance Scenarios + +1. **Given** [initial state], **When** [action], **Then** [expected outcome] +2. **Given** [initial state], **When** [action], **Then** [expected outcome] + +### Edge Cases + +- What happens when [boundary condition]? +- How does system handle [error scenario]? + +## Requirements *(mandatory)* + +### Functional Requirements + +- **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"] +- **FR-002**: System MUST [specific capability, e.g., "validate email addresses"] +- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"] +- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"] +- **FR-005**: System MUST [behavior, e.g., "log all security events"] + +Example of marking unclear requirements: + +- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?] +- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified] + +### Key Entities *(include if feature involves data)* + +- **[Entity 1]**: [What it represents, key attributes without implementation] +- **[Entity 2]**: [What it represents, relationships to other entities] + +--- + **Feature Branch**: `[###-feature-name]` **Created**: [DATE] **Status**: Draft @@ -55,44 +93,6 @@ When creating this spec from a user prompt: --- -## User Scenarios & Testing *(mandatory)* - -### Primary User Story - -[Describe the main user journey in plain language] - -### Acceptance Scenarios - -1. **Given** [initial state], **When** [action], **Then** [expected outcome] -2. **Given** [initial state], **When** [action], **Then** [expected outcome] - -### Edge Cases - -- What happens when [boundary condition]? -- How does system handle [error scenario]? - -## Requirements *(mandatory)* - -### Functional Requirements - -- **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"] -- **FR-002**: System MUST [specific capability, e.g., "validate email addresses"] -- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"] -- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"] -- **FR-005**: System MUST [behavior, e.g., "log all security events"] - -Example of marking unclear requirements: - -- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?] -- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified] - -### Key Entities *(include if feature involves data)* - -- **[Entity 1]**: [What it represents, key attributes without implementation] -- **[Entity 2]**: [What it represents, relationships to other entities] - ---- - ## Review & Acceptance Checklist *GATE: Automated checks run during main() execution* diff --git a/specs/002-merge-ci-yml/spec.md b/specs/002-merge-ci-yml/spec.md new file mode 100644 index 00000000..74867f50 --- /dev/null +++ b/specs/002-merge-ci-yml/spec.md @@ -0,0 +1,134 @@ +# Feature Specification: Merge CI.yml into Workflow.yml + +## User Scenarios & Testing + +### Primary User Story + +As a PowerShell module maintainer using the Process-PSModule framework, I want a single reusable workflow file that intelligently handles pull requests (with optional preview publishing), merged releases (with full publishing), and scheduled/manual test runs (without publishing), so that my repository configuration is simpler with fewer workflow files to maintain and the Nightly-Run.yml workflow is no longer needed. + +### Acceptance Scenarios + +1. **Given** a pull request is opened, **When** the workflow runs, **Then** all build/test/lint jobs execute and publish jobs run but skip publishing unless the PR has a "preview" label +2. **Given** a pull request with "preview" label is opened, **When** the workflow runs, **Then** the full pipeline executes including module and documentation publishing to preview environments +3. **Given** a pull request is merged to main, **When** the workflow runs, **Then** the full pipeline executes including module publishing to PowerShell Gallery and documentation deployment to GitHub Pages +4. **Given** the workflow is triggered by workflow_dispatch or schedule (nightly), **When** the workflow runs, **Then** all build/test/lint jobs execute but publish jobs (Publish-Site, Publish-Module) are skipped +5. **Given** test jobs fail during execution, **When** the workflow continues, **Then** code coverage aggregation and test result summarization still complete successfully +6. **Given** a repository currently uses both Process-PSModule.yml and Nightly-Run.yml, **When** migrated to the unified workflow, **Then** only Process-PSModule.yml is needed with workflow_dispatch and schedule triggers added + +### Edge Cases + +- What happens when a pull request is created? β†’ Should run full pipeline including publish jobs, but publish jobs contain logic to skip unless PR has "preview" label +- What happens when a pull request is merged to main? β†’ Should run full pipeline including all publishing steps +- How does the system handle test failures? β†’ Should continue to completion, including code coverage and test result summarization (existing behavior) +- What happens when triggered by workflow_dispatch or schedule (nightly run)? β†’ Should run all build/test/lint jobs but skip publishing steps (replaces separate Nightly-Run.yml workflow) +- What happens if a repository only needs CI functionality? β†’ Not applicable - all repositories using Process-PSModule run the full workflow + +--- + +## Requirements + +### Functional Requirements + +- **FR-001**: System MUST preserve all job definitions from CI.yml (Get-Settings, Build-Module, Build-Docs, Build-Site, Test-SourceCode, Lint-SourceCode, Test-Module, Test-ModuleLocal, BeforeAll-ModuleLocal, AfterAll-ModuleLocal, Get-TestResults, Get-CodeCoverage) +- **FR-002**: System MUST preserve all job definitions from workflow.yml (all jobs from CI.yml plus Publish-Site and Publish-Module) +- **FR-003**: System MUST maintain identical input parameters as defined in both workflows (Name, SettingsPath, Debug, Verbose, Version, Prerelease, WorkingDirectory) +- **FR-004**: System MUST maintain identical secrets definitions as defined in both workflows (APIKey, TEST_APP_ENT_CLIENT_ID, TEST_APP_ENT_PRIVATE_KEY, TEST_APP_ORG_CLIENT_ID, TEST_APP_ORG_PRIVATE_KEY, TEST_USER_ORG_FG_PAT, TEST_USER_USER_FG_PAT, TEST_USER_PAT) +- **FR-005**: System MUST support workflow_dispatch trigger to allow manual workflow execution +- **FR-006**: System MUST support schedule trigger for nightly automated test runs +- **FR-007**: Publish-Site job MUST execute when a pull request is merged to main and all prerequisite jobs succeed +- **FR-008**: Publish-Module job MUST execute when a pull request is merged to main and all prerequisite jobs succeed +- **FR-009**: Publish-Site job MUST execute when a pull request has the "preview" label and is not merged +- **FR-010**: Publish-Module job MUST execute when a pull request has the "preview" label and is not merged (with preview/prerelease publishing logic) +- **FR-011**: Publish-Site and Publish-Module jobs MUST be skipped when triggered via workflow_dispatch or schedule +- **FR-012**: System MUST maintain all job dependencies and execution order as defined in the original workflows +- **FR-013**: System MUST continue executing code coverage and test result jobs even when test jobs fail +- **FR-014**: System MUST maintain all conditional logic for job execution (if conditions) from both workflows +- **FR-015**: Repositories using Process-PSModule MUST be able to reference a single workflow file for all execution modes (PR, merge, scheduled, manual) +- **FR-016**: CI.yml file MUST be removed after successful migration to prevent confusion +- **FR-017**: Nightly-Run.yml workflow in module repositories MUST be removed as its functionality is absorbed into the unified workflow +- **FR-018**: Unified workflow MUST use write permissions (contents: write, pull-requests: write, statuses: write, pages: write, id-token: write) to support all execution modes + +### Key Entities + +- **CI.yml Workflow**: GitHub Actions reusable workflow file that currently handles continuous integration tasks (build, test, lint) with read-only permissions, used by Nightly-Run.yml for scheduled testing +- **workflow.yml Workflow**: GitHub Actions reusable workflow file that handles full pipeline including CI tasks plus publishing (site deployment, module publishing) with write permissions, used for pull request workflows +- **Nightly-Run.yml**: Repository-level workflow in module repos that triggers CI.yml on a schedule or manual dispatch for testing without publishing +- **Process-PSModule.yml**: Repository-level workflow in module repos that triggers workflow.yml for pull request and merge operations +- **Job Definitions**: Reusable workflow jobs that perform specific operations (Get-Settings, Build-Module, Test-Module, etc.) +- **Publish Jobs**: Publish-Site and Publish-Module jobs that deploy documentation and modules, with conditional execution based on trigger type and PR labels +- **Trigger Types**: Different invocation methods (pull_request opened/synchronized, pull_request merged, workflow_dispatch, schedule) that determine which jobs execute +- **Preview Label**: Pull request label that enables preview publishing for testing changes before merge +- **Permissions**: GitHub Actions permission sets that control what the workflow can do (write permissions needed for all modes) + +--- + +**Feature Branch**: `002-merge-ci-yml` +**Created**: 2025-10-02 +**Status**: Draft +**Input**: User description: "Merge ci.yml into workflow.yml, so that we can deduplicate and two workflows and have less workflows in the repos that use this process." + +## Execution Flow (main) + +1. Parse user description from Input + β†’ Feature description is clear: consolidate two similar workflow files +2. Extract key concepts from description + β†’ Actors: PowerShell module maintainers, CI/CD pipeline + β†’ Actions: Merge workflows, deduplicate configuration, reduce workflow count + β†’ Data: Workflow YAML files, job definitions, permissions + β†’ Constraints: Must maintain existing functionality +3. For each unclear aspect: + β†’ No major ambiguities; requirements are well-defined +4. Fill User Scenarios & Testing section + β†’ Primary user flow: Repository using Process-PSModule framework references a single workflow +5. Generate Functional Requirements + β†’ Requirements focus on workflow consolidation and preservation of functionality +6. Identify Key Entities + β†’ CI.yml workflow, workflow.yml, job definitions, permissions +7. Run Review Checklist + β†’ No implementation details included; focused on user value +8. Return: SUCCESS (spec ready for planning) + +--- + +## ⚑ Quick Guidelines + +- βœ… Focus on WHAT users need and WHY +- ❌ Avoid HOW to implement (no tech stack, APIs, code structure) +- πŸ‘₯ Written for business stakeholders, not developers + +### Section Requirements + +- **Mandatory sections**: Must be completed for every feature +- **Optional sections**: Include only when relevant to the feature +- When a section doesn't apply, remove it entirely (don't leave as "N/A") + +--- + +## Review & Acceptance Checklist + +### 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] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +--- + +## Execution Status + +- [x] User description parsed +- [x] Key concepts extracted +- [x] Ambiguities marked (none identified) +- [x] User scenarios defined +- [x] Requirements generated +- [x] Entities identified +- [x] Review checklist passed From aca4162bcd7da16d72d41644d38e3dbebaa01633 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 02:48:15 +0200 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Consolidate=20CI.?= =?UTF-8?q?yml=20into=20a=20unified=20workflow,=20removing=20redundant=20f?= =?UTF-8?q?iles=20and=20simplifying=20repository=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- specs/001-merge-workflows/spec.md | 136 ++++++++++++++++++++++++++++++ specs/002-merge-ci-yml/spec.md | 134 ----------------------------- 2 files changed, 136 insertions(+), 134 deletions(-) create mode 100644 specs/001-merge-workflows/spec.md delete mode 100644 specs/002-merge-ci-yml/spec.md diff --git a/specs/001-merge-workflows/spec.md b/specs/001-merge-workflows/spec.md new file mode 100644 index 00000000..6b57a0a0 --- /dev/null +++ b/specs/001-merge-workflows/spec.md @@ -0,0 +1,136 @@ +# Feature Specification: Merge CI and Main Workflows + +## User Scenarios & Testing *(mandatory)* + +### Primary User Story + +As a PowerShell module maintainer, I want a unified workflow that handles both continuous integration (on PRs) and release publishing (on merge), with optional scheduled runs for nightly testing, so that I can reduce workflow duplication and simplify my repository configuration. + +**⚠️ BREAKING CHANGE**: This will remove CI.yml, requiring all consuming repositories to update their workflow references from `CI.yml` to `workflow.yml`. + +### Acceptance Scenarios + +1. **Given** a pull request is opened/synchronized, **When** the workflow runs, **Then** it should build, test, lint, and collect test results/code coverage, but NOT publish the module/docs unless the PR has a "preview" label +2. **Given** a pull request is merged to main, **When** the workflow completes successfully, **Then** it should run all build, test, and quality checks AND publish both the module and documentation site +3. **Given** a scheduled/manual workflow run is triggered, **When** the workflow executes, **Then** it should run all build and test steps but skip the publish steps entirely +4. **Given** tests fail in any stage, **When** the workflow continues, **Then** it should still complete code coverage and test result summarization steps (no early termination) +5. **Given** a module repository uses this workflow, **When** it's configured, **Then** the Nightly-Run.yml workflow should no longer be needed +6. **Given** an existing repository references CI.yml, **When** upgrading to the new version, **Then** it must update references from `CI.yml` to `workflow.yml` or the workflow will fail + +### Edge Cases + +- What happens when test jobs fail but we still need code coverage reports? The workflow should continue processing with `always()` conditions +- How does the system handle preview publishes on non-merged PRs? The Publish-Module action already has logic to check for "preview" label and handle versioning accordingly +- What if a repository has no tests configured? The workflow should skip test-related jobs gracefully using conditional logic +- What happens to repositories that don't update their CI.yml references? Their workflows will fail with "workflow not found" errors + +## Requirements *(mandatory)* + +### Functional Requirements + +- **FR-001**: The merged workflow MUST support three trigger modes: pull request events, scheduled runs, and manual dispatch +- **FR-002**: The workflow MUST execute build, test, and quality checks for all trigger types +- **FR-003**: The workflow MUST publish module and documentation ONLY when: + - Trigger is a merged pull request (to main), OR + - Trigger is an open/synchronized pull request with "preview" label +- **FR-004**: The workflow MUST skip publish steps when triggered by schedule or workflow_dispatch +- **FR-005**: Test result summarization and code coverage jobs MUST run even when test jobs fail (using `always()` and `!cancelled()` conditions) +- **FR-006**: The workflow MUST maintain all current permissions for different operations (contents, pull-requests, statuses, pages, id-token) +- **FR-007**: The workflow MUST support all existing inputs (Name, SettingsPath, Debug, Verbose, Version, Prerelease, WorkingDirectory) +- **FR-008**: The workflow MUST support all existing secrets (APIKey, test credentials) +- **FR-009**: Module repositories using this workflow MUST be able to remove their Nightly-Run.yml workflow file +- **FR-010**: The CI.yml workflow file in Process-PSModule MUST be removed as it becomes redundant (BREAKING CHANGE) +- **FR-011**: The workflow MUST include a concurrency group to cancel in-progress runs when new commits are pushed to the same PR +- **FR-012**: The workflow name and run-name MUST provide clear context about what triggered the run +- **FR-013**: Documentation MUST clearly indicate the breaking change and provide migration steps for consuming repositories +- **FR-014**: The release MUST be a major version bump due to the breaking change of removing CI.yml + +### Breaking Changes + +- **BC-001**: CI.yml will be deleted - all references to `PSModule/Process-PSModule/.github/workflows/CI.yml@vX` must be updated to `workflow.yml` +- **BC-002**: Repositories with Nightly-Run.yml or similar workflows calling CI.yml must update their configurations before upgrading + +### Migration Requirements + +- **MR-001**: Consuming repositories MUST update workflow references from `CI.yml` to `workflow.yml` +- **MR-002**: Consuming repositories SHOULD remove their Nightly-Run.yml files and update their main workflow to include schedule/dispatch triggers +- **MR-003**: Migration documentation MUST include before/after examples of workflow configurations + +### Key Entities + +- **Workflow Triggers**: Pull request events (opened, reopened, synchronize, closed, labeled), schedule (cron), workflow_dispatch +- **Job Dependencies**: Get-Settings β†’ Build β†’ Test β†’ Summarization β†’ Publish (conditional) +- **Execution Contexts**: PR validation mode (no publish unless preview), merge mode (full publish), scheduled mode (no publish) +- **Consuming Repositories**: Any repository using CI.yml that must migrate to workflow.yml + +--- + +**Feature Branch**: `001-merge-workflows` +**Created**: 2025-10-02 +**Status**: Draft +**Input**: User description: "Merge ci.yml into workflow.yml, so that we can deduplicate and two workflows and have less workflows in the repos that use this process. When the pr is created, we do want publish to run, but its got logic to not publish, unless the pull request has a 'preview' label. When merged, the full pipeline should run. When there are failures in tests, it should continue working as it is (completing code coverage and test result summarization). A repo will NEVER only need ci functionality. Check the Template-PSModule's workflow to see how its currently configured for module repos. We want to basically remove the need for the nightly run pipeline, and update the main process workflow with a schedule and a workflow dispatch. When its running in this mode, we do not want the publish steps (module and docs) to run." + +## Execution Flow (main) + +1. βœ… Parse user description from Input +2. βœ… Extract key concepts from description + - Merge two workflow files (CI.yml and workflow.yml) + - Support three execution modes: PR validation, merge/publish, scheduled testing + - Maintain existing failure handling behavior + - Eliminate Nightly-Run.yml from module repositories +3. βœ… Generate Functional Requirements + - All requirements are testable through workflow execution +4. βœ… Identify Key Entities + - Workflow triggers and execution contexts +5. βœ… Run Review Checklist + - No implementation details included + - All requirements clear and testable + +--- + +## ⚑ Quick Guidelines + +- βœ… Focus on WHAT users need and WHY +- ❌ Avoid HOW to implement (no tech stack, APIs, code structure) +- πŸ‘₯ Written for business stakeholders, not developers + +### Section Requirements + +- **Mandatory sections**: Must be completed for every feature +- **Optional sections**: Include only when relevant to the feature +- When a section doesn't apply, remove it entirely (don't leave as "N/A") + +--- + +## Review & Acceptance Checklist + +*GATE: Automated checks run during main() execution* + +### 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] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +--- + +## Execution Status + +*Updated by main() during processing* + +- [x] User description parsed +- [x] Key concepts extracted +- [x] Ambiguities marked (none found) +- [x] User scenarios defined +- [x] Requirements generated +- [x] Entities identified +- [x] Review checklist passed diff --git a/specs/002-merge-ci-yml/spec.md b/specs/002-merge-ci-yml/spec.md deleted file mode 100644 index 74867f50..00000000 --- a/specs/002-merge-ci-yml/spec.md +++ /dev/null @@ -1,134 +0,0 @@ -# Feature Specification: Merge CI.yml into Workflow.yml - -## User Scenarios & Testing - -### Primary User Story - -As a PowerShell module maintainer using the Process-PSModule framework, I want a single reusable workflow file that intelligently handles pull requests (with optional preview publishing), merged releases (with full publishing), and scheduled/manual test runs (without publishing), so that my repository configuration is simpler with fewer workflow files to maintain and the Nightly-Run.yml workflow is no longer needed. - -### Acceptance Scenarios - -1. **Given** a pull request is opened, **When** the workflow runs, **Then** all build/test/lint jobs execute and publish jobs run but skip publishing unless the PR has a "preview" label -2. **Given** a pull request with "preview" label is opened, **When** the workflow runs, **Then** the full pipeline executes including module and documentation publishing to preview environments -3. **Given** a pull request is merged to main, **When** the workflow runs, **Then** the full pipeline executes including module publishing to PowerShell Gallery and documentation deployment to GitHub Pages -4. **Given** the workflow is triggered by workflow_dispatch or schedule (nightly), **When** the workflow runs, **Then** all build/test/lint jobs execute but publish jobs (Publish-Site, Publish-Module) are skipped -5. **Given** test jobs fail during execution, **When** the workflow continues, **Then** code coverage aggregation and test result summarization still complete successfully -6. **Given** a repository currently uses both Process-PSModule.yml and Nightly-Run.yml, **When** migrated to the unified workflow, **Then** only Process-PSModule.yml is needed with workflow_dispatch and schedule triggers added - -### Edge Cases - -- What happens when a pull request is created? β†’ Should run full pipeline including publish jobs, but publish jobs contain logic to skip unless PR has "preview" label -- What happens when a pull request is merged to main? β†’ Should run full pipeline including all publishing steps -- How does the system handle test failures? β†’ Should continue to completion, including code coverage and test result summarization (existing behavior) -- What happens when triggered by workflow_dispatch or schedule (nightly run)? β†’ Should run all build/test/lint jobs but skip publishing steps (replaces separate Nightly-Run.yml workflow) -- What happens if a repository only needs CI functionality? β†’ Not applicable - all repositories using Process-PSModule run the full workflow - ---- - -## Requirements - -### Functional Requirements - -- **FR-001**: System MUST preserve all job definitions from CI.yml (Get-Settings, Build-Module, Build-Docs, Build-Site, Test-SourceCode, Lint-SourceCode, Test-Module, Test-ModuleLocal, BeforeAll-ModuleLocal, AfterAll-ModuleLocal, Get-TestResults, Get-CodeCoverage) -- **FR-002**: System MUST preserve all job definitions from workflow.yml (all jobs from CI.yml plus Publish-Site and Publish-Module) -- **FR-003**: System MUST maintain identical input parameters as defined in both workflows (Name, SettingsPath, Debug, Verbose, Version, Prerelease, WorkingDirectory) -- **FR-004**: System MUST maintain identical secrets definitions as defined in both workflows (APIKey, TEST_APP_ENT_CLIENT_ID, TEST_APP_ENT_PRIVATE_KEY, TEST_APP_ORG_CLIENT_ID, TEST_APP_ORG_PRIVATE_KEY, TEST_USER_ORG_FG_PAT, TEST_USER_USER_FG_PAT, TEST_USER_PAT) -- **FR-005**: System MUST support workflow_dispatch trigger to allow manual workflow execution -- **FR-006**: System MUST support schedule trigger for nightly automated test runs -- **FR-007**: Publish-Site job MUST execute when a pull request is merged to main and all prerequisite jobs succeed -- **FR-008**: Publish-Module job MUST execute when a pull request is merged to main and all prerequisite jobs succeed -- **FR-009**: Publish-Site job MUST execute when a pull request has the "preview" label and is not merged -- **FR-010**: Publish-Module job MUST execute when a pull request has the "preview" label and is not merged (with preview/prerelease publishing logic) -- **FR-011**: Publish-Site and Publish-Module jobs MUST be skipped when triggered via workflow_dispatch or schedule -- **FR-012**: System MUST maintain all job dependencies and execution order as defined in the original workflows -- **FR-013**: System MUST continue executing code coverage and test result jobs even when test jobs fail -- **FR-014**: System MUST maintain all conditional logic for job execution (if conditions) from both workflows -- **FR-015**: Repositories using Process-PSModule MUST be able to reference a single workflow file for all execution modes (PR, merge, scheduled, manual) -- **FR-016**: CI.yml file MUST be removed after successful migration to prevent confusion -- **FR-017**: Nightly-Run.yml workflow in module repositories MUST be removed as its functionality is absorbed into the unified workflow -- **FR-018**: Unified workflow MUST use write permissions (contents: write, pull-requests: write, statuses: write, pages: write, id-token: write) to support all execution modes - -### Key Entities - -- **CI.yml Workflow**: GitHub Actions reusable workflow file that currently handles continuous integration tasks (build, test, lint) with read-only permissions, used by Nightly-Run.yml for scheduled testing -- **workflow.yml Workflow**: GitHub Actions reusable workflow file that handles full pipeline including CI tasks plus publishing (site deployment, module publishing) with write permissions, used for pull request workflows -- **Nightly-Run.yml**: Repository-level workflow in module repos that triggers CI.yml on a schedule or manual dispatch for testing without publishing -- **Process-PSModule.yml**: Repository-level workflow in module repos that triggers workflow.yml for pull request and merge operations -- **Job Definitions**: Reusable workflow jobs that perform specific operations (Get-Settings, Build-Module, Test-Module, etc.) -- **Publish Jobs**: Publish-Site and Publish-Module jobs that deploy documentation and modules, with conditional execution based on trigger type and PR labels -- **Trigger Types**: Different invocation methods (pull_request opened/synchronized, pull_request merged, workflow_dispatch, schedule) that determine which jobs execute -- **Preview Label**: Pull request label that enables preview publishing for testing changes before merge -- **Permissions**: GitHub Actions permission sets that control what the workflow can do (write permissions needed for all modes) - ---- - -**Feature Branch**: `002-merge-ci-yml` -**Created**: 2025-10-02 -**Status**: Draft -**Input**: User description: "Merge ci.yml into workflow.yml, so that we can deduplicate and two workflows and have less workflows in the repos that use this process." - -## Execution Flow (main) - -1. Parse user description from Input - β†’ Feature description is clear: consolidate two similar workflow files -2. Extract key concepts from description - β†’ Actors: PowerShell module maintainers, CI/CD pipeline - β†’ Actions: Merge workflows, deduplicate configuration, reduce workflow count - β†’ Data: Workflow YAML files, job definitions, permissions - β†’ Constraints: Must maintain existing functionality -3. For each unclear aspect: - β†’ No major ambiguities; requirements are well-defined -4. Fill User Scenarios & Testing section - β†’ Primary user flow: Repository using Process-PSModule framework references a single workflow -5. Generate Functional Requirements - β†’ Requirements focus on workflow consolidation and preservation of functionality -6. Identify Key Entities - β†’ CI.yml workflow, workflow.yml, job definitions, permissions -7. Run Review Checklist - β†’ No implementation details included; focused on user value -8. Return: SUCCESS (spec ready for planning) - ---- - -## ⚑ Quick Guidelines - -- βœ… Focus on WHAT users need and WHY -- ❌ Avoid HOW to implement (no tech stack, APIs, code structure) -- πŸ‘₯ Written for business stakeholders, not developers - -### Section Requirements - -- **Mandatory sections**: Must be completed for every feature -- **Optional sections**: Include only when relevant to the feature -- When a section doesn't apply, remove it entirely (don't leave as "N/A") - ---- - -## Review & Acceptance Checklist - -### 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] Scope is clearly bounded -- [x] Dependencies and assumptions identified - ---- - -## Execution Status - -- [x] User description parsed -- [x] Key concepts extracted -- [x] Ambiguities marked (none identified) -- [x] User scenarios defined -- [x] Requirements generated -- [x] Entities identified -- [x] Review checklist passed From c60b8199790ee093bbaeacba6e9999b5498cef88 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 07:43:47 +0200 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20Markdown=20?= =?UTF-8?q?and=20PowerShell=20style=20guidelines=20for=20consistency=20acr?= =?UTF-8?q?oss=20documentation=20and=20scripts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/instructions/md.instructions.md | 278 +++++++ .github/instructions/pwsh.instructions.md | 837 ++++++++++++++++++++++ 2 files changed, 1115 insertions(+) create mode 100644 .github/instructions/md.instructions.md create mode 100644 .github/instructions/pwsh.instructions.md diff --git a/.github/instructions/md.instructions.md b/.github/instructions/md.instructions.md new file mode 100644 index 00000000..07a4951c --- /dev/null +++ b/.github/instructions/md.instructions.md @@ -0,0 +1,278 @@ +--- +applyTo: '**/*.md' +description: Markdown style guidelines for consistency across documentation. +--- + +# Markdown Style Guidelines + +This document defines the markdown style guidelines for all markdown files in this repository. These rules follow common markdown linter best practices and ensure consistency across documentation. + +## Headings + +- Use ATX-style headings (`#`) instead of Setext-style (underlines) +- Include a space after the hash marks: `# Heading` not `#Heading` +- Use only one top-level heading (`#`) per document +- Do not skip heading levels (e.g., don't go from `#` to `###`) +- Surround headings with blank lines (one before, one after, excluding the first heading in the document unless preceded by frontmatter) +- Do not use trailing punctuation in headings (no periods, colons, etc.) +- Use sentence case for headings unless referring to proper nouns or code identifiers + +**Good:** + +```markdown +# Main heading + +## Subsection + +### Details +``` + +**Bad:** + +```markdown +#No space after hash +### Skipped level 2 +## Heading with period. +``` + +## Lists + +- Use consistent list markers throughout the document (`-` for unordered, `1.` for ordered) +- Do not add blank lines between list items (unless item contains multiple paragraphs) +- Indent nested lists by 2 spaces for unordered, 3 spaces for ordered +- Use `1.` for all ordered list items (auto-numbering) or number them sequentially +- Surround lists with blank lines (one before, one after) +- Use `-` for unordered lists (not `*` or `+`) + +**Good:** + +```markdown +Here is a list: + +- First item +- Second item +- Third item + +Another list: + +1. First step +1. Second step +1. Third step +``` + +**Bad:** + +```markdown +No blank line before list: +- Item one + +- Blank lines between items +- Not needed + +* Wrong marker ++ Mixed markers +``` + +## Code Blocks + +- Always use fenced code blocks (triple backticks) with language identifiers +- Always include a blank line before and after code blocks +- Specify the language for syntax highlighting (`bash`, `python`, `markdown`, `json`, etc.) +- Use `plaintext` or `text` if no specific language applies +- Indent code blocks at the same level as surrounding content + +**Good:** + +```markdown +Here is an example: + +\`\`\`bash +echo "Hello, world!" +\`\`\` + +The command prints a message. +``` + +**Bad:** + +```markdown +No language identifier: +\`\`\` +code here +\`\`\` +No blank lines before/after code blocks. +``` + +## Links + +- Use reference-style links for repeated URLs +- Use relative paths for internal links (relative to the current file) +- Always provide link text in square brackets: `[text](url)` +- Do not use bare URLs (wrap them: ``) +- For internal repository links, use relative paths starting with `./` or `../` +- Use `.md` extension for links to markdown files + +**Good:** + +```markdown +See the [installation guide](../docs/installation.md) for details. + +Check out [GitHub][gh] and [GitLab][gl] for hosting. + +[gh]: https://github.com +[gl]: https://gitlab.com +``` + +**Bad:** + +```markdown +Absolute path: [guide](/docs/installation.md) +Missing extension: [guide](../docs/installation) +Bare URL: Visit https://example.com +``` + +## Tables + +- Use tables when content follows a consistent structure (instead of lists) +- Align columns using hyphens for readability +- Include header row separator with at least 3 hyphens per column +- Surround tables with blank lines (one before, one after) +- Use pipes (`|`) to separate columns +- Align content within columns for readability (optional but recommended) + +**Good:** + +```markdown +Here is a comparison: + +| Feature | Supported | Notes | +|---------|-----------|-------| +| Feature A | Yes | Fully supported | +| Feature B | No | Planned for v2 | +| Feature C | Partial | Beta feature | + +The table shows current status. +``` + +**Bad:** + +```markdown +Using list when table is better: +- Feature A: Yes - Fully supported +- Feature B: No - Planned for v2 +- Feature C: Partial - Beta feature +``` + +## Emphasis + +- Use `*` or `_` for emphasis (italic), `**` or `__` for strong emphasis (bold) +- Be consistent within a document (prefer `*` and `**`) +- Do not use emphasis for headings +- Use backticks for code/technical terms, not emphasis + +**Good:** + +```markdown +This is *emphasized* text. +This is **strong** text. +Use the `--verbose` flag for details. +``` + +**Bad:** + +```markdown +This is _emphasized_ text with **strong** mixed styles. +Use the *--verbose* flag (should be backticks). +``` + +## Line Length + +- Wrap prose at 80-120 characters per line +- Do not wrap code blocks, tables, or URLs +- Break after sentences or at natural phrase boundaries +- Empty lines do not count toward line length + +## Whitespace + +- Use a single blank line to separate blocks of content +- Do not use multiple consecutive blank lines +- End files with a single newline character +- Do not use trailing whitespace at the end of lines +- Use spaces (not tabs) for indentation + +## Other Rules + +### Horizontal Rules + +- Use three hyphens (`---`) for horizontal rules +- Surround horizontal rules with blank lines + +**Good:** + +```markdown +Section one content. + +--- + +Section two content. +``` + +### Blockquotes + +- Use `>` for blockquotes with a space after +- Surround blockquotes with blank lines +- Use multiple `>` for nested quotes + +**Good:** + +```markdown +As the docs state: + +> This is an important note. +> It spans multiple lines. + +Back to regular text. +``` + +### Images + +- Use alt text for all images: `![alt text](path/to/image.png)` +- Use relative paths for repository images +- Prefer reference-style for repeated images + +**Good:** + +```markdown +![Architecture diagram](../media/architecture.png) + +See the [logo][logo-img] above. + +[logo-img]: ./images/logo.png +``` + +### HTML + +- Avoid HTML in markdown when possible +- Use HTML only for features not supported by markdown +- Close all HTML tags properly + +### File Names + +- Use lowercase for markdown file names +- Use hyphens (`-`) not underscores (`_`) to separate words +- Use `.md` extension (not `.markdown`) + +**Examples:** + +- `installation-guide.md` βœ… +- `Installation_Guide.markdown` ❌ + +## Linting + +To validate markdown files against these guidelines, use a markdown linter such as: + +- [markdownlint](https://github.com/DavidAnson/markdownlint) +- [remark-lint](https://github.com/remarkjs/remark-lint) +- [superlinter](https://github.com/super-linter/super-linter) + +Configure the linter to enforce these rules in your CI/CD pipeline. diff --git a/.github/instructions/pwsh.instructions.md b/.github/instructions/pwsh.instructions.md new file mode 100644 index 00000000..cc91256f --- /dev/null +++ b/.github/instructions/pwsh.instructions.md @@ -0,0 +1,837 @@ +--- +applyTo: '**/*.{ps1,psm1}' +description: PowerShell style guidelines for consistency across scripts and modules. +--- + +# PowerShell Style Guidelines + +This document defines the PowerShell style guidelines for all PowerShell files in this repository. These rules follow PowerShell best practices, the One True Brace Style (OTBS), and community standards. + +## Brace Style (OTBS - One True Brace Style) + +- Opening braces on the same line as the statement (OTBS) +- Closing braces on their own line, aligned with the statement +- Use braces even for single-line statements in control structures +- No empty lines immediately after opening braces or before closing braces + +**Good:** + +```powershell +function Get-Example { + param($Name) + + if ($Name) { + Write-Output "Hello, $Name" + } else { + Write-Output "Hello, World" + } +} + +foreach ($item in $items) { + Get-Item $item +} +``` + +**Bad:** + +```powershell +function Get-Example +{ + # Opening brace should be on same line +} + +if ($condition) + Write-Output "Missing braces" + +if ($condition) { Write-Output "All on one line" } +``` + +## Naming Conventions + +### Functions and Cmdlets + +- Use approved PowerShell verbs (Get, Set, New, Remove, etc.) +- Follow Verb-Noun naming pattern with PascalCase +- Use singular nouns +- Be specific and descriptive + +**Good:** + +```powershell +function Get-UserProfile { } +function Set-ConfigValue { } +function New-DatabaseConnection { } +function Remove-TempFile { } +``` + +**Bad:** + +```powershell +function GetUser { } # Missing hyphen +function get-user { } # Wrong case +function Do-Something { } # Non-standard verb +function Get-Users { } # Should be singular unless always plural +``` + +### Parameters and Variables + +- Use PascalCase for parameters and public variables +- Use camelCase for private/local variables +- Use descriptive names, avoid abbreviations unless well-known +- Prefix boolean variables with verbs like `is`, `has`, `should` +- Append 'At' 'In' 'On' for timestamp/location variables +- Use `$_` for pipeline variables +- Avoid using reserved words as names +- Avoid using automatic variables for custom variables +- Parameter and variable names can be alphanumeric and include underscores. +- The colon character `:` and `.` are significant in PowerShell syntax, if they are a part of text, they must be escaped (`). + +**Good:** + +```powershell +$userName = "John" +$isValid = $true +$hasPermission = $false +$totalCount = 0 + +param( + [string]$ConfigPath, + [switch]$Force +) +``` + +**Bad:** + +```powershell +$usr = "John" # Too abbreviated +$valid = $true # Boolean should be $isValid +$TOTAL_COUNT = 0 # Wrong case style +``` + +### Constants + +- Use PascalCase with descriptive names +- Mark as `[System.Management.Automation.Language.ReadOnlyAttribute]` or use `Set-Variable -Option ReadOnly` + +**Good:** + +```powershell +$MaxRetries = 3 +$DefaultTimeout = 30 +Set-Variable -Name ApiEndpoint -Value "https://api.example.com" -Option ReadOnly +``` + +## Parameters + +- Always use `[OutputType()]`, `[CmdletBinding()]` and `param()` block at the top of functions +- Use parameter attributes for validation +- Provide meaningful parameter names with PascalCase +- Use type constraints for parameters. +- Have a space between the type and the parameter name +- Group mandatory parameters first +- Use `[switch]` for boolean flags that default to `$false`. +- Add help text with parameter descriptions (inside the param block) + + +**Good:** + +```powershell +function Get-UserData { + <# + .SYNOPSIS + Retrieves user data from the database. + + .DESCRIPTION + Retrieves user data from the database. + + .EXAMPLE + Get-UserData -UserId "12345" -IncludeDeleted + #> + [CmdletBinding()] + param( + # The unique identifier of the user. + [Parameter(Mandatory, Position = 0)] + [ValidateNotNullOrEmpty()] + [string] $UserId, + + # Include deleted users in the results. + [Parameter()] + [switch] $IncludeDeleted + ) + + # Function body +} +``` + +**Bad:** + +```powershell +function Get-UserData($id, $del) { + # No param block, no types, unclear names +} +``` + +## Indentation and Whitespace + +- Use 4 spaces for indentation (not tabs) +- No trailing whitespace at end of lines +- End files with a single newline character +- Use blank lines to separate logical blocks of code +- No blank lines immediately after opening braces or before closing braces +- One space after commas in arrays and parameters +- One space around operators (`=`, `+`, `-`, `-eq`, `-ne`, etc.) + +**Good:** + +```powershell +function Process-Data { + <# + ... Docs + #> + [CmdletBinding()] + param( + [Parameter(Mandatory, Position = 0)] + [ValidateNotNullOrEmpty()] + [array] $Items + ) + + $results = @() + + foreach ($item in $Items) { + $processed = Format-Item $item + $results += $processed + } + + return $results +} +``` + +**Bad:** + +```powershell +function Process-Data{ + param($Items) + + $results=@() + foreach($item in $Items){ + $processed=Format-Item $item + $results+=$processed + } + + return $results + +} +``` + +## Comments + +- Use `#` for single-line comments +- Use `<# ... #>` for multi-line comments and help documentation +- Place comments on their own line above the code they describe +- Use comment-based help for functions (`.SYNOPSIS`, `.DESCRIPTION`, `.EXAMPLE`) +- Put comment-based help first, inside the function body, before any code. This makes it cleaner to move, and collapse code. +- Do not use '.PARAMETER' for parameters in comment-based help, use inline comments instead inside the param block above + each of the parameters. +- Each section of comment-based help should have a blank line between them. +- The comment-based help must be indented to align with the function definition. +- Keep comments up to date with code changes. +- The code should say what it is doing, comments should explain why. + +**Good:** + +```powershell +function New-UserAccount { +<# + .SYNOPSIS + Creates a new user account. + + .DESCRIPTION + Creates a new user account with the specified username and email. + Validates the email format before creation. + + .EXAMPLE + New-UserAccount -UserName 'jdoe' -Email 'jdoe@example.com' + + Creates a new user account for jdoe with email jdoe@example.com. + + .LINK + https://example.com/docs/New-UserAccount +#> + [CmdletBinding()] + param( + # The username for the new account. + [Parameter(Mandatory)] + [string] $UserName, + + # The email address for the new account. + [Parameter(Mandatory)] + [string] $Email + ) + + # Validate email format before processing + if ($Email -notmatch '^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$') { + throw "Invalid email format" + } + + # Create the user account + New-Object PSObject -Property @{ + UserName = $UserName + Email = $Email + } +} +``` + +**Bad:** + +```powershell +function New-UserAccount { + param($UserName, $Email) + # Check email + if ($Email -notmatch '^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$') { throw "Invalid email format" } + New-Object PSObject -Property @{UserName = $UserName; Email = $Email} # Create user +} +``` + +## String Handling + +- Use single quotes for strings that don't need variable expansion +- Use double quotes only for strings with variables or escape sequences +- Use here-strings (`@"..."@` or `@'...'@`) for multi-line strings +- Use `-f` operator or string interpolation for formatting +- Avoid string concatenation with `+` in loops (use arrays or StringBuilder) + +**Good:** + +```powershell +$name = 'John' +$greeting = "Hello, $name" +$path = 'C:\Temp\file.txt' +$message = "The value is: {0}" -f $value + +$multiLine = @" +This is a +multi-line string +with variable: $name +"@ +``` + +**Bad:** + +```powershell +$name = "John" # Should use single quotes (no variables) +$greeting = 'Hello, $name' # Variable won't expand +$message = "The value is: " + $value # Use formatting instead +``` + +## Control Structures + +### If/Else Statements + +- Always use braces, even for single statements +- Opening brace on same line (OTBS) +- Use `elseif` (one word) not `else if` +- One space before opening brace +- Comparison operators on separate lines for readability in complex conditions + +**Good:** + +```powershell +if ($condition) { + Do-Something +} elseif ($otherCondition) { + Do-SomethingElse +} else { + Do-Default +} + +# Complex condition +if ($user.IsActive -and + $user.HasPermission -and + $user.Age -gt 18) { + Grant-Access +} +``` + +**Bad:** + +```powershell +if ($condition) +{ # Brace should be on same line + Do-Something +} + +if ($condition) Do-Something # Missing braces + +if($condition){ # Missing spaces + Do-Something +} +``` + +### Loops + +- Use appropriate loop construct (foreach, for, while, do-while) +- Always use braces +- Opening brace on same line (OTBS) +- Prefer `foreach` for collections over `for` when index not needed + +**Good:** + +```powershell +foreach ($item in $collection) { + Process-Item $item +} + +for ($i = 0; $i -lt $count; $i++) { + Process-Index $i +} + +while ($condition) { + Update-Condition +} +``` + +**Bad:** + +```powershell +foreach ($item in $collection) +{ # Brace should be on same line + Process-Item $item +} + +foreach ($item in $collection) Process-Item $item # Missing braces +``` + +### Switch Statements + +- Opening brace on same line +- Indent case statements by 4 spaces +- Use `break` or `continue` explicitly when needed +- Use `default` for fallback cases + +**Good:** + +```powershell +switch ($value) { + 'Option1' { + Do-FirstThing + } + 'Option2' { + Do-SecondThing + } + default { + Do-DefaultThing + } +} +``` + +## Error Handling + +- Use try/catch/finally blocks for error handling +- Be specific with catch blocks (catch specific exception types) +- Always provide meaningful error messages +- Use `throw` for unrecoverable errors +- Use `Write-Error` for non-terminating errors +- Set `$ErrorActionPreference` appropriately + +**Good:** + +```powershell +function Get-FileContent { + param([string]$Path) + + try { + if (-not (Test-Path $Path)) { + throw "File not found: $Path" + } + + $content = Get-Content -Path $Path -ErrorAction Stop + return $content + } catch [System.IO.IOException] { + Write-Error "IO error reading file: $_" + throw + } catch { + Write-Error "Unexpected error: $_" + throw + } finally { + # Cleanup code here + } +} +``` + +**Bad:** + +```powershell +function Get-FileContent { + param([string]$Path) + + try { + Get-Content -Path $Path + } catch { + # Swallowing errors silently + } +} +``` + +## Output and Logging + +- Use `Write-Output` for function return values (or implicit return) +- Avoid `Write-Host` use `Write-Information` or `Write-Output` instead. +- Use `Write-Verbose` for detailed operation information +- Use `Write-Debug` for debugging information +- Use `Write-Warning` for warnings +- Use `Write-Error` for errors +- Use `Write-Information` for informational messages (PS 5.0+) + +**Good:** + +```powershell +function Get-ProcessedData { + [CmdletBinding()] + param($Data) + + Write-Verbose "Processing $($Data.Count) items" + + $result = Process-Data $Data + + if ($result.Warnings) { + Write-Warning "Processing completed with warnings" + } + + Write-Output $result +} +``` + +**Bad:** + +```powershell +function Get-ProcessedData { + param($Data) + + Write-Host "Processing data..." # Should use Write-Verbose + + $result = Process-Data $Data + + Write-Host $result # Should use Write-Output +} +``` + +## Pipeline + +- Design functions to accept pipeline input when appropriate +- Use `[Parameter(ValueFromPipeline = $true)]` for pipeline parameters +- Implement `process` block for pipeline-aware functions +- Use `begin` and `end` blocks when initialization or cleanup needed + +**Good:** + +```powershell +function Update-Item { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true, ValueFromPipeline = $true)] + [PSCustomObject]$Item + ) + + begin { + $count = 0 + } + + process { + # Process each item from pipeline + $Item.LastModified = Get-Date + $count++ + Write-Output $Item + } + + end { + Write-Verbose "Processed $count items" + } +} + +# Usage +$items | Update-Item +``` + +## Arrays and Hashtables + +- Use `@()` for empty arrays +- Use `@{}` for empty hashtables +- Use consistent formatting for multi-line collections +- One item per line for readability in multi-line collections +- Trailing comma optional but allowed on last item +- Align key-value pairs in hashtables for readability +- Use splatting for functions with many parameters + +**Good:** + +```powershell +$emptyArray = @() +$numbers = @(1, 2, 3, 4, 5) + +$multiLineArray = @( + 'First item' + 'Second item' + 'Third item' +) + +$hashtable = @{ + Name = 'John' + Age = 30 + City = 'Seattle' +} + +$complexHash = @{ + Server = @{ + Name = 'WebServer01' + Port = 8080 + } + Database = @{ + Name = 'MainDB' + Port = 5432 + } +} +``` + +**Bad:** + +```powershell +$array = 1, 2, 3, 4, 5 # Use @() syntax + +$hashtable = @{Name = 'John'; Age = 30; City = 'Seattle'} # Multi-line for readability +``` + +## Splatting + +- Use splatting for functions with many parameters +- Create hashtable with parameters before splatting +- Use `@` symbol for splatting (not `$`) + +**Good:** + +```powershell +$params = @{ + Path = 'C:\Temp' + Filter = '*.txt' + Recurse = $true + ErrorAction = 'Stop' +} + +Get-ChildItem @params +``` + +**Bad:** + +```powershell +Get-ChildItem -Path 'C:\Temp' -Filter '*.txt' -Recurse $true -ErrorAction 'Stop' +``` + +## Comparison Operators + +- Use PowerShell comparison operators (`-eq`, `-ne`, `-gt`, `-lt`, `-ge`, `-le`) +- Don't use C-style operators (`==`, `!=`, `>`, `<`) +- Use `-like` for wildcard matching, `-match` for regex +- Use `-contains` for collection membership, not `-eq` +- Add `-i` prefix for case-insensitive (default) or `-c` for case-sensitive +- Caution with $null comparisons. Comparison order is important depending if the variable is a single item or a collection. + - `$null -eq $var` is usually safer for collections as it won't error if $var is $null or empty. + +**Good:** + +```powershell +if ($value -eq 10) { } +if ($name -like 'John*') { } +if ($email -match '^[\w-\.]+@') { } +if ($list -contains $item) { } +if ($name -ceq 'JOHN') { } # Case-sensitive +if ($null -eq $collection) { } # Safe null check for collections +``` + +**Bad:** + +```powershell +if ($value == 10) { } # Wrong operator +if ($list -eq $item) { } # Use -contains for collections +if ($collection -eq $null) { } # Can error if $collection is $null or empty +``` + +## Script Structure + +- Use `#Requires` statements at the top for version/module requirements +- Place param block after `#Requires` and comment-based help +- Group related functions together +- Separate sections with comments +- End script with single newline + +**Good:** + +```powershell +#Requires -Version 7.4 + +<# + .SYNOPSIS + Script for managing user accounts. + + .DESCRIPTION + This script provides functions to create, update, and delete user accounts. +#> + +[CmdletBinding()] +param( + [string]$ConfigPath = ".\config.json" +) + +# Script-level variables +$ErrorActionPreference = 'Stop' + +#region Helper functions +function Get-ConfigData { + param([string]$Path) + # Implementation +} + +function New-UserAccount { + param($UserName, $Email) + # Implementation +} +#endregion + +# Script execution +try { + $config = Get-ConfigData -Path $ConfigPath + # Main logic +} catch { + Write-Error "Script failed: $_" + exit 1 +} +``` + +## Performance Considerations + +- Avoid `Write-Host` in production scripts, instead use `Write-Information` +- Use `ArrayList` collection instead of `@()` arrays in loops. +- Use `-Filter` parameter instead of piping to `Where-Object` when available +- Avoid unnecessary pipeline operations +- Use `.ForEach()` and `.Where()` methods for better performance on large collections + +**Good:** + +```powershell +# Efficient array building +$results = [System.Collections.Generic.List[PSObject]]::new() +foreach ($item in $collection) { + $results.Add($processedItem) +} + +# Efficient filtering +Get-ChildItem -Path C:\Temp -Filter *.txt + +# Method syntax for performance +$filtered = $collection.Where({ $_.Value -gt 10 }) +``` + +**Bad:** + +```powershell +# Inefficient array building +$results = @() +foreach ($item in $collection) { + $results += $processedItem # Creates new array each iteration +} + +# Inefficient filtering +Get-ChildItem -Path C:\Temp | Where-Object { $_.Name -like '*.txt' } +``` + +## Line Length + +- Wrap lines at 100-120 characters +- Use backtick (`` ` ``) for line continuation (sparingly), prefer splatting +- Prefer breaking at natural points (after commas, operators, pipes) +- Align continued lines for readability + +**Good:** + +```powershell +$result = Get-Something -Parameter1 $value1 ` + -Parameter2 $value2 ` + -Parameter3 $value3 + +# Better: Use splatting +$params = @{ + Parameter1 = $value1 + Parameter2 = $value2 + Parameter3 = $value3 +} +$result = Get-Something @params +``` + +## Testing + +- Write Pester tests for all functions +- Name test files `*.Tests.ps1` +- Group tests with `Describe` and `Context` blocks +- Use `It` blocks for individual test cases +- Use `Should` assertions +- Use `BeforeAll` and `AfterAll` for setup/teardown + +**Good:** + +```powershell +Describe 'Get-UserAccount' { + Context 'When user exists' { + It 'Should return user object' { + $result = Get-UserAccount -UserId '123' + $result | Should -Not -BeNullOrEmpty + $result.UserId | Should -Be '123' + } + } + + Context 'When user does not exist' { + It 'Should throw error' { + { Get-UserAccount -UserId '999' } | Should -Throw + } + } +} +``` + +## Security Best Practices + +- Never hardcode credentials or secrets +- Use `SecureString` for sensitive data +- Use `Get-Credential` for credential prompts +- Validate all user input +- Use `-WhatIf` and `-Confirm` for destructive operations +- Avoid `Invoke-Expression` with user input + +**Good:** + +```powershell +function Remove-UserData { + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$UserId + ) + + if ($PSCmdlet.ShouldProcess($UserId, "Remove user data")) { + # Perform deletion + } +} + +# Get credentials securely +$cred = Get-Credential -Message "Enter admin credentials" +``` + +**Bad:** + +```powershell +$password = "MyPassword123" # Hardcoded password +Invoke-Expression $userInput # Security risk +``` + +## Related Resources + +- [PowerShell Practice and Style Guide](https://poshcode.gitbook.io/powershell-practice-and-style/) +- [PowerShell Best Practices](https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/cmdlet-development-guidelines) +- [PSScriptAnalyzer Rules](https://github.com/PowerShell/PSScriptAnalyzer) From 3570dc173a9e169254ed59ba245d87de722c843e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 08:42:44 +0200 Subject: [PATCH 4/5] Enhance workflow and iteration support across commands - Updated implement.prompt.md to include workflow modes (Local and Fork) and iteration support for task completion tracking. - Enhanced plan.prompt.md with workflow modes, iteration detection, and refined task generation based on existing plans. - Improved specify.prompt.md to support fork contributions, detailed branch naming, and specification writing/updating processes. - Modified tasks.prompt.md to incorporate workflow modes, iteration detection, and task updating mechanisms. - Refined create-new-feature.ps1 script to manage branch creation based on current branch context and existing feature detection. - Added a new constitution-template.md for project governance and principles documentation. - Removed obsolete spec.md for the Merge CI and Main Workflows feature. --- .github/prompts/constitution.prompt.md | 63 ++++++-- .github/prompts/implement.prompt.md | 80 +++++++++-- .github/prompts/plan.prompt.md | 84 +++++++++-- .github/prompts/specify.prompt.md | 130 +++++++++++++++-- .github/prompts/tasks.prompt.md | 68 +++++++-- .../scripts/powershell/create-new-feature.ps1 | 81 ++++++++--- .specify/templates/constitution-template.md | 50 +++++++ specs/001-merge-workflows/spec.md | 136 ------------------ 8 files changed, 486 insertions(+), 206 deletions(-) create mode 100644 .specify/templates/constitution-template.md delete mode 100644 specs/001-merge-workflows/spec.md diff --git a/.github/prompts/constitution.prompt.md b/.github/prompts/constitution.prompt.md index 23341d5e..00b4b8ad 100644 --- a/.github/prompts/constitution.prompt.md +++ b/.github/prompts/constitution.prompt.md @@ -1,5 +1,5 @@ --- -description: Create or update the project constitution from interactive or provided principle inputs, ensuring all dependent templates stay in sync. +description: Create (if absent) or iteratively update the project constitution from interactive or provided inputs, ensuring all dependent templates stay in sync. --- # Constitution @@ -10,15 +10,49 @@ User input: $ARGUMENTS -You are updating the project constitution at `.specify/memory/constitution.md`. This file is a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). Your job is to (a) collect/derive concrete values, (b) fill the template precisely, and (c) propagate any amendments across dependent artifacts. +**Note**: This command operates on the local repository's constitution and does not typically require fork-specific logic, as constitutional changes are usually made within the repository itself rather than targeting upstream repositories. + +You are (a) creating or (b) iterating on the project constitution at `.specify/memory/constitution.md`. + +Two operating modes: + +1. Initial Creation Mode (constitution file does NOT exist): + - Copy `.specify/templates/constitution-template.md` to `.specify/memory/constitution.md` verbatim before processing. + - Treat the copied file as a TEMPLATE containing placeholder tokens in square brackets (e.g. `[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`). + - Produce an initial version (default `1.0.0` unless the user specifies otherwise). Ratification date = today (unless user supplies one). Last amended date = same as ratification. +2. Iteration Mode (constitution file already exists): + - Load the existing `.specify/memory/constitution.md` (NOT the template) as the authoritative current constitution. + - Do NOT re-copy the template. Only reference the template to discover any NEW placeholders/sections that could be adopted. + - Identify new functionality / sections / principles requested (from user input or arguments) and integrate them. + - If a new principle or governance rule appears to REPLACE or substantially OVERLAP an existing one, generate a Replacement Analysis Table and request user confirmation before destructive changes. If interactive confirmation is not possible in this run, mark the affected original item with `TODO(REVIEW_REPLACEMENT): Proposed replacement: ` and include in the Sync Impact Report under deferred actions. + - Preserve original ratification date. Increment version per rules below. Update last amended date to today if any material change occurs. + +Replacement Analysis Table (when overlap detected): + +| Existing Item | Proposed New / Change | Overlap Basis | Suggested Action | +|---------------|-----------------------|---------------|------------------| +| | <incoming title / change> | e.g. semantic similarity, scope duplication | Replace / Merge / Keep Both | + +Heuristics for overlap: +- Title similarity score (case-insensitive) >= 0.6 (rough string similarity) OR +- >50% of bullet rules conceptually duplicate (same verbs/nouns) OR +- Governance rule introduces stricter variant of an existing rule. + +If ambiguity remains, prefer non-destructive addition plus TODO marker. Follow this execution flow: -1. Load the existing constitution template at `.specify/memory/constitution.md`. - - Identify every placeholder token of the form `[ALL_CAPS_IDENTIFIER]`. - **IMPORTANT**: The user might require less or more principles than the ones used in the template. If a number is specified, respect that - follow the general template. You will update the doc accordingly. +0. Existence Check & Mode Selection: + - If `.specify/memory/constitution.md` is missing β†’ enter Initial Creation Mode (copy template, then proceed). + - If it exists β†’ Iteration Mode (operate directly on existing file; treat remaining bracket tokens, if any, as still-to-be-resolved placeholders). + +1. Load Source Document: + - Creation Mode: load freshly copied `.specify/memory/constitution.md` (formerly the template). + - Iteration Mode: load existing `.specify/memory/constitution.md` and independently load `.specify/templates/constitution-template.md` only to detect any NEW placeholders/sections not yet present. + - Identify every placeholder token `[ALL_CAPS_IDENTIFIER]` still unresolved in the working constitution (not just in template). + - IMPORTANT: User may request changing the number of principles. Respect explicit user instruction; re-number or re-label as needed (maintain Roman numeral style if already in use; otherwise adopt consistent scheme). -2. Collect/derive values for placeholders: +2. Collect/derive values for placeholders (and new/changed content): - If user input (conversation) supplies a value, use it. - Otherwise infer from existing repo context (README, docs, prior constitution versions if embedded). - For governance dates: `RATIFICATION_DATE` is the original adoption date (if unknown ask or mark TODO), `LAST_AMENDED_DATE` is today if changes are made, otherwise keep previous. @@ -28,17 +62,20 @@ Follow this execution flow: * PATCH: Clarifications, wording, typo fixes, non-semantic refinements. - If version bump type ambiguous, propose reasoning before finalizing. -3. Draft the updated constitution content: +3. Draft / Merge updated constitution content: + - In Iteration Mode, integrate new principles/sections with minimal disruption: + * Retain stable identifiers (e.g., keep existing principle numbering unless renumbering is explicitly required or gaps introduced by removals). + * When replacing, either (a) fully substitute content if user confirmed or (b) append revised content and mark old with `DEPRECATED:` prefix plus TODO for removal in a future major version. - Replace every placeholder with concrete text (no bracketed tokens left except intentionally retained template slots that the project has chosen not to define yetβ€”explicitly justify any left). - Preserve heading hierarchy and comments can be removed once replaced unless they still add clarifying guidance. - Ensure each Principle section: succinct name line, paragraph (or bullet list) capturing non‑negotiable rules, explicit rationale if not obvious. - Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations. 4. Consistency propagation checklist (convert prior checklist into active validations): - - Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles. - - Read `.specify/templates/spec-template.md` for scope/requirements alignmentβ€”update if constitution adds/removes mandatory sections or constraints. - - Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline). - - Read each command file in `.specify/templates/commands/*.md` (including this one) to verify no outdated references (agent-specific names like CLAUDE only) remain when generic guidance is required. + - Read [`.specify/templates/plan-template.md`](../../.specify/templates/plan-template.md) and ensure any "Constitution Check" or rules align with updated principles. + - Read [`.specify/templates/spec-template.md`](../../.specify/templates/spec-template.md) for scope/requirements alignmentβ€”update if constitution adds/removes mandatory sections or constraints. + - Read [`.specify/templates/tasks-template.md`](../../.specify/templates/tasks-template.md) and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline). + - Read each related prompt file in `.github/prompts/` (including this one) to verify no outdated agent-specific references remain (e.g., names tied to a specific LLM vendor) when generic guidance is required. - Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed. 5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update): @@ -46,8 +83,10 @@ Follow this execution flow: - List of modified principles (old title β†’ new title if renamed) - Added sections - Removed sections + - Deprecated (marked) sections pending removal - Templates requiring updates (βœ… updated / ⚠ pending) with file paths - Follow-up TODOs if any placeholders intentionally deferred. + - Replacement items needing confirmation (if any) 6. Validation before final output: - No remaining unexplained bracket tokens. @@ -55,7 +94,7 @@ Follow this execution flow: - Dates ISO format YYYY-MM-DD. - Principles are declarative, testable, and free of vague language ("should" β†’ replace with MUST/SHOULD rationale where appropriate). -7. Write the completed constitution back to `.specify/memory/constitution.md` (overwrite). +7. Write the completed constitution back to [`.specify/memory/constitution.md`](../../.specify/memory/constitution.md) (overwrite). Never write to the template path during iteration. 8. Output a final summary to the user with: - New version and bump rationale. diff --git a/.github/prompts/implement.prompt.md b/.github/prompts/implement.prompt.md index 0351c1aa..fcbf6eb4 100644 --- a/.github/prompts/implement.prompt.md +++ b/.github/prompts/implement.prompt.md @@ -10,7 +10,13 @@ User input: $ARGUMENTS -1. Run `.specify/scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute. +**Workflow Modes**: This command supports two modes: +- **Local (default)**: Work with the current repository (origin). No special configuration needed. +- **Fork**: Contribute to an upstream repository. Reads `.fork-info.json` created by `/specify`. + +**Iteration Support**: This command supports iterative implementation - you can run it multiple times to complete remaining tasks, fix issues, or add refinements. Task completion state is tracked in tasks.md with [X] markers. + +1. Run [`.specify/scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks`](../../.specify/scripts/powershell/check-prerequisites.ps1) from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute. 2. Load and analyze the implementation context: - **REQUIRED**: Read tasks.md for the complete task list and execution plan @@ -21,12 +27,18 @@ $ARGUMENTS - **IF EXISTS**: Read quickstart.md for integration scenarios 3. Parse tasks.md structure and extract: + - **Detect iteration state**: Check task completion markers + - Tasks marked [X] are complete - skip unless user requests changes + - Tasks marked [ ] are pending - these need implementation + - If all tasks are complete, check if user input requests additional work - **Task phases**: Setup, Tests, Core, Integration, Polish - **Task dependencies**: Sequential vs parallel execution rules - **Task details**: ID, description, file paths, parallel markers [P] - **Execution flow**: Order and dependency requirements 4. Execute implementation following the task plan: + - **Skip completed tasks**: Don't re-implement tasks marked [X] unless explicitly requested + - **Resume from last incomplete task**: Start with first [ ] task found - **Phase-by-phase execution**: Complete each phase before moving to the next - **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together - **Follow TDD approach**: Execute test tasks before their corresponding implementation tasks @@ -56,9 +68,22 @@ $ARGUMENTS - Report final status with summary of completed work 8. Create or update Pull Request: + - **Determine workflow mode and target repository**: + - Check if `.fork-info.json` exists in the feature directory (same directory as spec.md) + - **If exists** (fork mode): + - Validate required fields: `is_fork` (true), `upstream_owner` (non-empty), `upstream_repo` (non-empty) + - If validation fails, halt and instruct user: "Invalid fork configuration in `.fork-info.json`. Please run `/specify` again with complete fork information: upstream owner, upstream repo." + - Use `upstream_owner/upstream_repo` for all GitHub operations + - **If not exists** (local mode - default): + - Use the current repository (origin) for all GitHub operations + - **Determine PR operation**: + - If PR already exists for this branch, UPDATE it (description, status, labels) + - If no PR exists, CREATE a new one - **Target branch**: The PR must be against the default branch - **PR status**: The PR must not be draft, it should be ready for review - - **Determine PR type and icon** based on the changes: + - **Retrieve the issue title**: Get the title from the linked GitHub issue (created in `/specify`) from the target repository + - **Use the same title for the PR**: Verify the PR title matches the issue title exactly. If they differ, update the PR title to match the issue. + - If unable to retrieve the issue title, determine the PR type and icon based on the changes: | Type of change | Icon | Label | |-|-|-| @@ -69,20 +94,53 @@ $ARGUMENTS | Feature | πŸš€ | Minor | | Breaking change | 🌟 | Major | - - **PR title format**: `<Icon> [Type of change]: <Short description>` - - **PR description structure**: - * Start with a summary paragraph describing the key outcome and changes for user - * DO NOT add a title before the leading paragraph - * At the end of the PR paragraph, add a "- Fixes #<issue-number>" line to link the PR to the issue - * Follow with additional details answering Why, How, and What - * Avoid superfluous headers or sections - * We do not need details, we need to add what changes for the user of the code + - Fallback PR title format (if issue title unavailable): `<Icon> [Type of change]: <Short description>` + - **PR description structure** (formatted as a release note): + * Start with a user-focused summary paragraph describing what's new, improved, or fixed + * Write in past tense, focusing on capabilities and user benefits (e.g., "Added support for...", "Improved performance of...", "Fixed issue where...") + * DO NOT add a title or heading before the leading paragraph + * Keep the tone professional and concise - this will be read as a release note + * At the end of the summary paragraph, add "- Fixes #<issue-number>" to link the PR to the issue + * Follow with additional release-note style details: + - **What's Changed**: Brief bullet points of key changes from the user's perspective + - **Technical Details** (optional): Implementation notes if relevant for maintainers + - **Breaking Changes** (if applicable): Clear warning and migration guidance + - **Usage** (if applicable): Brief example or updated command syntax + * Avoid superfluous headers, verbose explanations, or internal implementation details + * Focus on what changes for the end user or developer using this code - **Apply appropriate label(s)** based on the type of change - **Link the PR** to the associated issue + - **After PR updates**: Update `.fork-info.json` (if it exists) with the latest PR number (if not already present) + + **GitHub Integration**: If GitHub tools or integrations are available (such as GitHub MCP Server or other GitHub integrations), use them to update the PR status and labels automatically in the target repository. If not available, provide these fallback commands with the correct repository: + ```bash + # Mark PR as ready for review + # If fork: gh pr ready <PR-number> --repo <upstream_owner>/<upstream_repo> + # If local: gh pr ready <PR-number> + gh pr ready <PR-number> + + # Update PR title to match issue (if needed) + gh pr edit <PR-number> --title "<Issue title>" + + # Update labels + gh pr edit <PR-number> --add-label "<Type>" + ``` 9. Update issue labels: - - Remove 'plan' label from the linked issue + - **Determine target repository** (same logic as step 8): + - Check if `.fork-info.json` exists in the feature directory + - If it exists and validated, use `upstream_owner/upstream_repo` + - If it doesn't exist, use the current repository (origin) + - Remove 'plan' label from the linked issue in the target repository - Add 'implement' label to the linked issue + - **After updating labels**: Ensure `.fork-info.json` (if it exists) has the issue number stored + + **GitHub Integration**: If GitHub tools are available, update labels automatically in the target repository. If not available, use: + ```bash + # If fork: gh issue edit <issue-number> --repo <upstream_owner>/<upstream_repo> ... + # If local: gh issue edit <issue-number> ... + gh issue edit <issue-number> --remove-label "Plan" --add-label "Implementation" + ``` 10. Update the constitution: - Read the [Constitution](../../.specify/memory/constitution.md) file. diff --git a/.github/prompts/plan.prompt.md b/.github/prompts/plan.prompt.md index f84d02c3..a54e6145 100644 --- a/.github/prompts/plan.prompt.md +++ b/.github/prompts/plan.prompt.md @@ -10,9 +10,18 @@ User input: $ARGUMENTS +**Workflow Modes**: This command supports two modes: +- **Local (default)**: Work with the current repository (origin). No special configuration needed. +- **Fork**: Contribute to an upstream repository. Reads `.fork-info.json` created by `/specify`. + +**Iteration Support**: This command detects whether you're creating a new plan or updating an existing one based on the presence of plan.md in the feature directory. + Given the implementation details provided as an argument, do this: -1. Run `.specify/scripts/powershell/setup-plan.ps1 -Json` from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute. +1. Run [`.specify/scripts/powershell/setup-plan.ps1 -Json`](../../.specify/scripts/powershell/setup-plan.ps1) from the repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. All future file paths must be absolute. + - **Detect iteration mode**: Check if IMPL_PLAN (plan.md) already exists: + - **If exists**: You are ITERATING on an existing plan. User input should guide refinements/additions to the existing plan content. + - **If not exists**: You are CREATING a new plan from scratch. - BEFORE proceeding, inspect FEATURE_SPEC for a `## Clarifications` section with at least one `Session` subheading. If missing or clearly ambiguous areas remain (vague adjectives, unresolved critical choices), PAUSE and instruct the user to run `/clarify` first to reduce rework. Only continue if: (a) Clarifications exist OR (b) an explicit user override is provided (e.g., "proceed without clarification"). Do not attempt to fabricate clarifications yourself. 2. Read and analyze the feature specification to understand: - The feature requirements and user stories @@ -20,14 +29,21 @@ Given the implementation details provided as an argument, do this: - Success criteria and acceptance criteria - Any technical constraints or dependencies mentioned -3. Read the constitution at `.specify/memory/constitution.md` to understand constitutional requirements. +3. Read the constitution at [`.specify/memory/constitution.md`](../../.specify/memory/constitution.md) to understand constitutional requirements. 4. Execute the implementation plan template: - - Load `.specify/templates/plan-template.md` (already copied to IMPL_PLAN path) + - Load [`.specify/templates/plan-template.md`](../../.specify/templates/plan-template.md) (already copied to IMPL_PLAN path) - Set Input path to FEATURE_SPEC - - Run the Execution Flow (main) function steps 1-9 - - The template is self-contained and executable - - Follow error handling and gate checks as specified + - **If ITERATING** (plan.md exists): + - Read existing plan.md content + - Identify what needs updating based on user input ($ARGUMENTS) + - Preserve existing valid content + - Refine or expand sections as needed + - Maintain consistency with existing decisions unless explicitly changing them + - **If CREATING** (new plan): + - Run the Execution Flow (main) function steps 1-9 + - The template is self-contained and executable + - Follow error handling and gate checks as specified - Let the template guide artifact generation in $SPECS_DIR: * Phase 0 generates research.md * Phase 1 generates data-model.md, contracts/, quickstart.md @@ -46,9 +62,22 @@ Given the implementation details provided as an argument, do this: - Push the branch (BRANCH) to remote 7. Create or update a Pull Request: + - **Determine workflow mode and target repository**: + - Check if `.fork-info.json` exists in the feature directory (same directory as spec.md) + - **If exists** (fork mode): + - Validate required fields: `is_fork` (true), `upstream_owner` (non-empty), `upstream_repo` (non-empty) + - If validation fails, halt and instruct user: "Invalid fork configuration in `.fork-info.json`. Please run `/specify` again with complete fork information: upstream owner, upstream repo." + - Use `upstream_owner/upstream_repo` for all GitHub operations + - **If not exists** (local mode - default): + - Use the current repository (origin) for all GitHub operations + - **Determine PR operation** (create vs update): + - If PR already exists for this branch, UPDATE it + - If no PR exists, CREATE a new one - The PR must be against the default branch. - - The PR must be opened as a draft. - - Determine the PR type and icon based on the changes: + - The PR must be opened as a draft (or remain draft if updating). + - **Retrieve the issue title**: Get the title from the linked GitHub issue (created in `/specify`) from the target repository + - **Use the same title for the PR**: The PR title must match the issue title exactly + - If unable to retrieve the issue title, determine the PR type and icon based on the changes: | Type of change | Icon | Label | |-|-|-| @@ -59,7 +88,7 @@ Given the implementation details provided as an argument, do this: | Feature | πŸš€ | Minor | | Breaking change | 🌟 | Major | - - Create PR title: `<Icon> [Type of change]: <Short description>` + - Fallback PR title format (if issue title unavailable): `<Icon> [Type of change]: <Short description>` - Create PR description: * Start with a summary paragraph describing the key outcome and changes for user * DO NOT add a title before the leading paragraph @@ -69,10 +98,45 @@ Given the implementation details provided as an argument, do this: * We do not need details, we need to add what changes for the user of the code - Apply appropriate label(s) based on the type of change - Link the PR to the associated issue + - **After PR creation**: Update `.fork-info.json` (if it exists) with the PR number: + ```json + { + "is_fork": true, + "upstream_owner": "...", + "upstream_repo": "...", + "detected_from": "user_input", + "created_at": "...", + "issue_number": <issue-number>, + "pr_number": <pr-number> + } + ``` + + **GitHub Integration**: If GitHub tools or integrations are available (such as GitHub MCP Server or other GitHub integrations), use them to create/update the PR and manage labels automatically in the target repository. If not available, provide these fallback commands with the correct repository: + ```bash + # Create draft PR + # If fork: gh pr create --repo <upstream_owner>/<upstream_repo> --draft ... + # If local: gh pr create --draft ... + gh pr create --draft --title "<Icon> [Type]: <Description>" --body "<PR description>" --label "<Type>" + + # Link to issue (if not using "Fixes #<issue>" in body) + gh pr edit <PR-number> --add-label "<Type>" + ``` 8. Update issue labels: - - Remove 'specification' label from the linked issue + - **Determine target repository** (same logic as step 7): + - Check if `.fork-info.json` exists in the feature directory + - If it exists and validated, use `upstream_owner/upstream_repo` + - If it doesn't exist, use the current repository (origin) + - Remove 'specification' label from the linked issue in the target repository - Add 'plan' label to the linked issue + - **After updating labels**: Update `.fork-info.json` (if it exists) with the issue number if not already present + + **GitHub Integration**: If GitHub tools are available, update labels automatically in the target repository. If not available, use: + ```bash + # If fork: gh issue edit <issue-number> --repo <upstream_owner>/<upstream_repo> ... + # If local: gh issue edit <issue-number> ... + gh issue edit <issue-number> --remove-label "Specification" --add-label "Plan" + ``` 9. Report results with branch name, PR URL, file paths, and generated artifacts. diff --git a/.github/prompts/specify.prompt.md b/.github/prompts/specify.prompt.md index aed6c171..8ee7c199 100644 --- a/.github/prompts/specify.prompt.md +++ b/.github/prompts/specify.prompt.md @@ -10,29 +10,133 @@ User input: $ARGUMENTS +**Workflow Modes**: This command supports two modes: +- **Local (default)**: Work with the current repository (origin). No special configuration needed. +- **Fork**: Contribute to an upstream repository. Requires explicit declaration with upstream owner/repo information. + +**Iteration Support**: This command detects whether you're creating a new feature or refining an existing one based on your current branch. + The text the user typed after `/specify` in the triggering message **is** the feature description. Assume you always have it available in this conversation even if `$ARGUMENTS` appears literally below. Do not ask the user to repeat it unless they provided an empty command. Given that feature description, do this: -1. Analyze the feature description and generate a concise, descriptive branch name: +1. **Check for fork contribution**: Analyze the user input for mentions of contributing to a fork or upstream repository. Look for phrases like: + - "fork contribution" + - "contributing to upstream" + - "fork of [owner/repo]" + - "upstream repo [owner/repo]" + - Any explicit mention of working on a fork + + If detected, extract the upstream repository information (owner/repo). + + **If fork contribution is detected but information is incomplete**, prompt the user: + ``` + Fork contribution detected. Please provide the following information: + - Upstream organization/owner name (e.g., "microsoft", "PSModule") + - Upstream repository name (e.g., "vscode", "PSModule") + - Git remote name for upstream (optional, defaults to "upstream") + + Example: "upstream owner: PSModule, upstream repo: Utilities" + ``` + + Wait for user response and re-parse the input before proceeding. Required fields: + - `upstream_owner` (string, non-empty) + - `upstream_repo` (string, non-empty) + - `upstream_remote` (string, optional, defaults to "upstream") + +2. Analyze the feature description and generate a concise, descriptive branch name: - Extract the core concept/action from the description (2-4 words maximum) - Use kebab-case format (lowercase, hyphen-separated) - Focus on the primary change or feature being implemented - Examples: "user-authentication", "merge-workflows", "api-rate-limiting", "fix-memory-leak" -2. Run the script `.specify/scripts/powershell/create-new-feature.ps1 -Json "$ARGUMENTS" -BranchName "<your-generated-name>"` from repo root and parse its JSON output for BRANCH_NAME and SPEC_FILE. All file paths must be absolute. + +3. Run the script [`.specify/scripts/powershell/create-new-feature.ps1 -Json -FeatureDescription "$ARGUMENTS" -BranchName "<your-generated-name>"`](../../.specify/scripts/powershell/create-new-feature.ps1) from repo root and parse its JSON output for BRANCH_NAME, SPEC_FILE, and IS_EXISTING_BRANCH. All file paths must be absolute. **IMPORTANT** You must only ever run this script once. The JSON is provided in the terminal as output - always refer to it to get the actual content you're looking for. - **NOTE** The script will prepend an auto-incremented feature number (e.g., `003-`) to your branch name. -3. Load `.specify/templates/spec-template.md` to understand required sections. -4. Write the specification to SPEC_FILE using the template structure, replacing placeholders with concrete details derived from the feature description (arguments) while preserving section order and headings. -5. Create a GitHub issue for this feature with: - - Title: Format as `<Icon> [Type]: <Feature name>` where: + **NOTE** + - The script will prepend an auto-incremented feature number (e.g., `003-`) to your branch name. + - If you're currently on `main` branch, a new feature branch will be created. + - If you're already on a feature branch (starts with 3 digits like `001-`, `002-`, etc.), you'll stay on that branch to iterate on the existing feature. + - This allows you to refine specifications without creating multiple branches for the same feature. + +4. **Store fork information (if detected in step 1)**: + - If the user indicated this is a fork contribution, create a `.fork-info.json` file in the feature directory (same location as SPEC_FILE) + - **Validate required fields before creating**: + - `upstream_owner` must be non-empty string + - `upstream_repo` must be non-empty string + - If validation fails, return to step 1 for clarification + - The file should contain: + ```json + { + "is_fork": true, + "upstream_owner": "<extracted-owner>", + "upstream_repo": "<extracted-repo>", + "upstream_remote": "<extracted-remote-or-upstream>", + "detected_from": "user_input", + "created_at": "<ISO8601-timestamp>" + } + ``` + - This file will be used by `/plan` and `/implement` commands to create issues and PRs in the correct repository + - If fork information was detected, inform the user: "Fork contribution detected. Issues and PRs will target `<upstream_owner>/<upstream_repo>`" + +5. Load [`.specify/templates/spec-template.md`](../../.specify/templates/spec-template.md) to understand required sections. + +6. **Write or update the specification**: + - **If IS_EXISTING_BRANCH is false** (new feature on main branch): + - Write a new specification to SPEC_FILE using the template structure + - Replace placeholders with concrete details derived from the feature description + - Preserve section order and headings from the template + - **If IS_EXISTING_BRANCH is true** (iterating on existing feature): + - Read the existing SPEC_FILE to understand the current specification + - Analyze the new feature description (arguments) to identify: + - New requirements or details to add + - Existing content that needs refinement or clarification + - Sections that may need updating based on the new input + - Update the specification incrementally: + - Preserve all existing content that remains relevant + - Add new sections or details where the new description adds information + - Refine or expand existing sections where the new description provides clarification + - Maintain the template structure and section order + - The goal is evolution, not replacement - build upon the existing spec rather than starting over + +7. Create or update a GitHub issue for this feature: + - **Determine target repository**: + - Check if `.fork-info.json` exists in the feature directory + - If it exists: + - Validate required fields: `is_fork` (true), `upstream_owner` (non-empty), `upstream_repo` (non-empty) + - If validation fails, prompt user for correct information (see step 1) + - Use `upstream_owner/upstream_repo` for all GitHub operations + - If it doesn't exist, use the current repository (origin) + - **Generate the issue title** in format `<Icon> [Type]: <Feature name>` where: - Icon: πŸ“– (Docs), πŸͺ² (Fix), ⚠️ (Security fix), 🩹 (Patch), πŸš€ (Feature/Minor), 🌟 (Breaking change/Major) - Type: Docs, Fix, Patch, Feature, or Breaking change - Feature name: Short description from the spec - - Body: The complete content of the SPEC_FILE (spec.md) - - Labels: - - `Specification` (always - indicates current phase) - - Type-based label: `Docs`, `Fix`, `Patch`, `Minor`, or `Major` based on the type of change -6. Report completion with branch name, spec file path, issue number, and readiness for the next phase. + - **Store the generated title** for use in subsequent workflow steps (plan, implement) + - **If IS_EXISTING_BRANCH is true**: + - Update the existing issue associated with this feature branch (if one exists) with the refined specification + - **Evaluate if the title needs updating**: If the feature scope has changed significantly (e.g., from patch to feature, or major functionality changes), update the issue title. For minor refinements or clarifications, keep the existing title. + - **If IS_EXISTING_BRANCH is false** (new branch): Create a new GitHub issue with: + - Title: Use the generated title format above + - Body: The complete content of the SPEC_FILE (spec.md). Remove the first H1 (#) header and the first H2 (##) header if they exist. We want the PR description to start with the "Primary user story" section. + - Labels: + - `Specification` (always - indicates current phase) + - Type-based label: `Docs`, `Fix`, `Patch`, `Minor`, or `Major` based on the type of change + + **GitHub Integration**: If GitHub MCP Server is available, use it to create/update the issue automatically in the target repository. ONLY IF NOT AVAILABLE; provide the appropriate fallback command with the correct repository: + + For new issues: + ```bash + # If fork: gh issue create --repo <upstream_owner>/<upstream_repo> ... + # If local: gh issue create ... + gh issue create --title "<Icon> [Type]: <Feature name>" --body-file <SPEC_FILE> --label "Specification,<Type>" --body "<existing body>\n\n---\n**Feature Branch**: `<BRANCH_NAME>`" + ``` + + For updating existing issues (find the issue number associated with the branch): + ```bash + # If fork: gh issue edit <issue-number> --repo <upstream_owner>/<upstream_repo> ... + # If local: gh issue edit <issue-number> ... + gh issue edit <issue-number> --body-file <SPEC_FILE> + ``` + +8. Report completion with branch name, spec file path, whether it's a new or updated feature, issue number, target repository (if fork), and readiness for the next phase. -Note: The script creates and checks out the new branch and initializes the spec file before writing. +Note: The script handles branch creation/reuse and initializes the spec file before writing. diff --git a/.github/prompts/tasks.prompt.md b/.github/prompts/tasks.prompt.md index a09cdf50..c766d9a3 100644 --- a/.github/prompts/tasks.prompt.md +++ b/.github/prompts/tasks.prompt.md @@ -10,7 +10,17 @@ User input: $ARGUMENTS -1. Run `.specify/scripts/powershell/check-prerequisites.ps1 -Json` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute. +**Workflow Modes**: This command supports two modes: +- **Local (default)**: Work with the current repository (origin). No special configuration needed. +- **Fork**: Contribute to an upstream repository. Reads `.fork-info.json` created by `/specify`. + +**Iteration Support**: This command detects whether you're creating new tasks or updating existing ones based on the presence of tasks.md in the feature directory. + +1. Run [`.specify/scripts/powershell/check-prerequisites.ps1 -Json`](../../.specify/scripts/powershell/check-prerequisites.ps1) from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute. + - **Detect iteration mode**: Check if FEATURE_DIR/tasks.md already exists: + - **If exists**: You are ITERATING on existing tasks. User input should guide refinements, additions, or reordering of tasks. + - **If not exists**: You are CREATING new tasks from scratch. + 2. Load and analyze available design documents: - Always read plan.md for tech stack and libraries - IF EXISTS: Read data-model.md for entities @@ -24,13 +34,21 @@ $ARGUMENTS - Generate tasks based on what's available 3. Generate tasks following the template: - - Use `.specify/templates/tasks-template.md` as the base - - Replace example tasks with actual tasks based on: - * **Setup tasks**: Project init, dependencies, linting - * **Test tasks [P]**: One per contract, one per integration scenario - * **Core tasks**: One per entity, service, CLI command, endpoint - * **Integration tasks**: DB connections, middleware, logging - * **Polish tasks [P]**: Unit tests, performance, docs + - **If ITERATING** (tasks.md exists): + - Read existing tasks.md content + - Identify what needs updating based on user input ($ARGUMENTS) + - Preserve completed tasks (marked with [X]) + - Add new tasks as needed + - Reorder or refine task descriptions + - Maintain task ID sequence + - **If CREATING** (new tasks): + - Use [`.specify/templates/tasks-template.md`](../../.specify/templates/tasks-template.md) as the base + - Replace example tasks with actual tasks based on: + * **Setup tasks**: Project init, dependencies, linting + * **Test tasks [P]**: One per contract, one per integration scenario + * **Core tasks**: One per entity, service, CLI command, endpoint + * **Integration tasks**: DB connections, middleware, logging + * **Polish tasks [P]**: Unit tests, performance, docs 4. Task generation rules: - Each contract file β†’ contract test task marked [P] @@ -59,6 +77,40 @@ $ARGUMENTS - Dependency notes - Parallel execution guidance +8. Update the Pull Request description: + - **Determine workflow mode and target repository**: + - Check if `.fork-info.json` exists in the feature directory (same location as plan.md) + - **If exists** (fork mode): + - Validate required fields: `is_fork` (true), `upstream_owner` (non-empty), `upstream_repo` (non-empty) + - If validation fails, halt and instruct user: "Invalid fork configuration in `.fork-info.json`. Please run `/specify` again with complete fork information: upstream owner, upstream repo." + - Use `upstream_owner/upstream_repo` for all GitHub operations + - **If not exists** (local mode - default): + - Use the current repository (origin) for all GitHub operations + - Append or update the tasks.md content in the existing PR description + - Format tasks with checkboxes for each task phase: + * Setup: `- [ ] T001: Task description` + * Tests: `- [ ] T002: Task description [P]` + * Core: `- [ ] T003: Task description` + * Integration: `- [ ] T004: Task description` + * Polish: `- [ ] T005: Task description [P]` + - Keep the existing PR content (summary, plan.md content, issue link) + - Add a section header before tasks: `## Implementation Tasks` + + **GitHub Integration**: If GitHub tools or integrations are available (such as GitHub MCP Server or other GitHub integrations), use them to update the PR description automatically in the target repository. If not available, provide this fallback command with the correct repository: + ```bash + # Get current PR description and append tasks + # If fork: gh pr view <PR-number> --repo <upstream_owner>/<upstream_repo> --json body --jq .body > temp_body.md + # If local: gh pr view <PR-number> --json body --jq .body > temp_body.md + gh pr view <PR-number> --json body --jq .body > temp_body.md + cat tasks.md >> temp_body.md + # If fork: gh pr edit <PR-number> --repo <upstream_owner>/<upstream_repo> --body-file temp_body.md + # If local: gh pr edit <PR-number> --body-file temp_body.md + gh pr edit <PR-number> --body-file temp_body.md + rm temp_body.md + ``` + +9. Report completion with task count, file path, and PR update status. + Context for task generation: $ARGUMENTS The tasks.md should be immediately executable - each task must be specific enough that an LLM can complete it without additional context. diff --git a/.specify/scripts/powershell/create-new-feature.ps1 b/.specify/scripts/powershell/create-new-feature.ps1 index 6e8d717f..7ab08058 100644 --- a/.specify/scripts/powershell/create-new-feature.ps1 +++ b/.specify/scripts/powershell/create-new-feature.ps1 @@ -54,26 +54,69 @@ if (Test-Path $specsDir) { $next = $highest + 1 $featureNum = ('{0:000}' -f $next) -# Use provided BranchName if available, otherwise generate from feature description -if ($BranchName) { - # Sanitize the provided branch name - $branchSuffix = $BranchName.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' -} else { - # Fallback: Generate from feature description (first 3 words) - $branchSuffix = $featureDesc.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' - $words = ($branchSuffix -split '-') | Where-Object { $_ } | Select-Object -First 3 - $branchSuffix = [string]::Join('-', $words) +# Determine if we should create a new branch or stay on the current one +$shouldCreateBranch = $false +$currentBranch = '' +$isExistingFeature = $false + +if ($hasGit) { + try { + $currentBranch = git rev-parse --abbrev-ref HEAD 2>$null + if ($LASTEXITCODE -eq 0) { + # Create new branch only if we're on 'main' or a branch that doesn't start with 3 digits + if ($currentBranch -eq 'main' -or $currentBranch -notmatch '^\d{3}-') { + $shouldCreateBranch = $true + } else { + # We're on a feature branch, reuse it + $isExistingFeature = $true + $branchName = $currentBranch + + # Extract feature number from existing branch + if ($branchName -match '^(\d{3})') { + $featureNum = $matches[1] + } + + Write-Verbose "Staying on existing feature branch: $branchName" + } + } + } catch { + Write-Warning 'Failed to get current branch name' + $shouldCreateBranch = $true + } } -$branchName = "$featureNum-$branchSuffix" +# Only generate new branch name if we need to create a new branch +if ($shouldCreateBranch) { + # Use provided BranchName if available, otherwise generate from feature description + if ($BranchName) { + # Sanitize the provided branch name + $branchSuffix = $BranchName.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' + } else { + # Fallback: Generate from feature description (first 3 words) + $branchSuffix = $featureDesc.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' + $words = ($branchSuffix -split '-') | Where-Object { $_ } | Select-Object -First 3 + $branchSuffix = [string]::Join('-', $words) + } -if ($hasGit) { + $branchName = "$featureNum-$branchSuffix" +} + +if ($hasGit -and $shouldCreateBranch) { try { git checkout -b $branchName | Out-Null } catch { Write-Warning "Failed to create git branch: $branchName" } -} else { +} elseif (-not $hasGit) { + # If no git, still generate a branch name for directory structure + if ($BranchName) { + $branchSuffix = $BranchName.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' + } else { + $branchSuffix = $featureDesc.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', '' + $words = ($branchSuffix -split '-') | Where-Object { $_ } | Select-Object -First 3 + $branchSuffix = [string]::Join('-', $words) + } + $branchName = "$featureNum-$branchSuffix" Write-Warning "[specify] Warning: Git repository not detected; skipped branch creation for $branchName" } @@ -93,10 +136,12 @@ $env:SPECIFY_FEATURE = $branchName if ($Json) { $obj = [PSCustomObject]@{ - BRANCH_NAME = $branchName - SPEC_FILE = $specFile - FEATURE_NUM = $featureNum - HAS_GIT = $hasGit + BRANCH_NAME = $branchName + SPEC_FILE = $specFile + FEATURE_NUM = $featureNum + HAS_GIT = $hasGit + IS_EXISTING_BRANCH = $isExistingFeature + CURRENT_BRANCH = $currentBranch } $obj | ConvertTo-Json -Compress } else { @@ -104,5 +149,9 @@ if ($Json) { Write-Output "SPEC_FILE: $specFile" Write-Output "FEATURE_NUM: $featureNum" Write-Output "HAS_GIT: $hasGit" + Write-Output "IS_EXISTING_BRANCH: $isExistingFeature" + if ($isExistingFeature) { + Write-Output "Reusing existing feature branch: $branchName" + } Write-Output "SPECIFY_FEATURE environment variable set to: $branchName" } diff --git a/.specify/templates/constitution-template.md b/.specify/templates/constitution-template.md new file mode 100644 index 00000000..1ed8d77a --- /dev/null +++ b/.specify/templates/constitution-template.md @@ -0,0 +1,50 @@ +# [PROJECT_NAME] Constitution +<!-- Example: Spec Constitution, TaskFlow Constitution, etc. --> + +## Core Principles + +### [PRINCIPLE_1_NAME] +<!-- Example: I. Library-First --> +[PRINCIPLE_1_DESCRIPTION] +<!-- Example: Every feature starts as a standalone library; Libraries must be self-contained, independently testable, documented; Clear purpose required - no organizational-only libraries --> + +### [PRINCIPLE_2_NAME] +<!-- Example: II. CLI Interface --> +[PRINCIPLE_2_DESCRIPTION] +<!-- Example: Every library exposes functionality via CLI; Text in/out protocol: stdin/args β†’ stdout, errors β†’ stderr; Support JSON + human-readable formats --> + +### [PRINCIPLE_3_NAME] +<!-- Example: III. Test-First (NON-NEGOTIABLE) --> +[PRINCIPLE_3_DESCRIPTION] +<!-- Example: TDD mandatory: Tests written β†’ User approved β†’ Tests fail β†’ Then implement; Red-Green-Refactor cycle strictly enforced --> + +### [PRINCIPLE_4_NAME] +<!-- Example: IV. Integration Testing --> +[PRINCIPLE_4_DESCRIPTION] +<!-- Example: Focus areas requiring integration tests: New library contract tests, Contract changes, Inter-service communication, Shared schemas --> + +### [PRINCIPLE_5_NAME] +<!-- Example: V. Observability, VI. Versioning & Breaking Changes, VII. Simplicity --> +[PRINCIPLE_5_DESCRIPTION] +<!-- Example: Text I/O ensures debuggability; Structured logging required; Or: MAJOR.MINOR.BUILD format; Or: Start simple, YAGNI principles --> + +## [SECTION_2_NAME] +<!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. --> + +[SECTION_2_CONTENT] +<!-- Example: Technology stack requirements, compliance standards, deployment policies, etc. --> + +## [SECTION_3_NAME] +<!-- Example: Development Workflow, Review Process, Quality Gates, etc. --> + +[SECTION_3_CONTENT] +<!-- Example: Code review requirements, testing gates, deployment approval process, etc. --> + +## Governance +<!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan --> + +[GOVERNANCE_RULES] +<!-- Example: All PRs/reviews must verify compliance; Complexity must be justified; Use [GUIDANCE_FILE] for runtime development guidance --> + +**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE] +<!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 --> \ No newline at end of file diff --git a/specs/001-merge-workflows/spec.md b/specs/001-merge-workflows/spec.md deleted file mode 100644 index 6b57a0a0..00000000 --- a/specs/001-merge-workflows/spec.md +++ /dev/null @@ -1,136 +0,0 @@ -# Feature Specification: Merge CI and Main Workflows - -## User Scenarios & Testing *(mandatory)* - -### Primary User Story - -As a PowerShell module maintainer, I want a unified workflow that handles both continuous integration (on PRs) and release publishing (on merge), with optional scheduled runs for nightly testing, so that I can reduce workflow duplication and simplify my repository configuration. - -**⚠️ BREAKING CHANGE**: This will remove CI.yml, requiring all consuming repositories to update their workflow references from `CI.yml` to `workflow.yml`. - -### Acceptance Scenarios - -1. **Given** a pull request is opened/synchronized, **When** the workflow runs, **Then** it should build, test, lint, and collect test results/code coverage, but NOT publish the module/docs unless the PR has a "preview" label -2. **Given** a pull request is merged to main, **When** the workflow completes successfully, **Then** it should run all build, test, and quality checks AND publish both the module and documentation site -3. **Given** a scheduled/manual workflow run is triggered, **When** the workflow executes, **Then** it should run all build and test steps but skip the publish steps entirely -4. **Given** tests fail in any stage, **When** the workflow continues, **Then** it should still complete code coverage and test result summarization steps (no early termination) -5. **Given** a module repository uses this workflow, **When** it's configured, **Then** the Nightly-Run.yml workflow should no longer be needed -6. **Given** an existing repository references CI.yml, **When** upgrading to the new version, **Then** it must update references from `CI.yml` to `workflow.yml` or the workflow will fail - -### Edge Cases - -- What happens when test jobs fail but we still need code coverage reports? The workflow should continue processing with `always()` conditions -- How does the system handle preview publishes on non-merged PRs? The Publish-Module action already has logic to check for "preview" label and handle versioning accordingly -- What if a repository has no tests configured? The workflow should skip test-related jobs gracefully using conditional logic -- What happens to repositories that don't update their CI.yml references? Their workflows will fail with "workflow not found" errors - -## Requirements *(mandatory)* - -### Functional Requirements - -- **FR-001**: The merged workflow MUST support three trigger modes: pull request events, scheduled runs, and manual dispatch -- **FR-002**: The workflow MUST execute build, test, and quality checks for all trigger types -- **FR-003**: The workflow MUST publish module and documentation ONLY when: - - Trigger is a merged pull request (to main), OR - - Trigger is an open/synchronized pull request with "preview" label -- **FR-004**: The workflow MUST skip publish steps when triggered by schedule or workflow_dispatch -- **FR-005**: Test result summarization and code coverage jobs MUST run even when test jobs fail (using `always()` and `!cancelled()` conditions) -- **FR-006**: The workflow MUST maintain all current permissions for different operations (contents, pull-requests, statuses, pages, id-token) -- **FR-007**: The workflow MUST support all existing inputs (Name, SettingsPath, Debug, Verbose, Version, Prerelease, WorkingDirectory) -- **FR-008**: The workflow MUST support all existing secrets (APIKey, test credentials) -- **FR-009**: Module repositories using this workflow MUST be able to remove their Nightly-Run.yml workflow file -- **FR-010**: The CI.yml workflow file in Process-PSModule MUST be removed as it becomes redundant (BREAKING CHANGE) -- **FR-011**: The workflow MUST include a concurrency group to cancel in-progress runs when new commits are pushed to the same PR -- **FR-012**: The workflow name and run-name MUST provide clear context about what triggered the run -- **FR-013**: Documentation MUST clearly indicate the breaking change and provide migration steps for consuming repositories -- **FR-014**: The release MUST be a major version bump due to the breaking change of removing CI.yml - -### Breaking Changes - -- **BC-001**: CI.yml will be deleted - all references to `PSModule/Process-PSModule/.github/workflows/CI.yml@vX` must be updated to `workflow.yml` -- **BC-002**: Repositories with Nightly-Run.yml or similar workflows calling CI.yml must update their configurations before upgrading - -### Migration Requirements - -- **MR-001**: Consuming repositories MUST update workflow references from `CI.yml` to `workflow.yml` -- **MR-002**: Consuming repositories SHOULD remove their Nightly-Run.yml files and update their main workflow to include schedule/dispatch triggers -- **MR-003**: Migration documentation MUST include before/after examples of workflow configurations - -### Key Entities - -- **Workflow Triggers**: Pull request events (opened, reopened, synchronize, closed, labeled), schedule (cron), workflow_dispatch -- **Job Dependencies**: Get-Settings β†’ Build β†’ Test β†’ Summarization β†’ Publish (conditional) -- **Execution Contexts**: PR validation mode (no publish unless preview), merge mode (full publish), scheduled mode (no publish) -- **Consuming Repositories**: Any repository using CI.yml that must migrate to workflow.yml - ---- - -**Feature Branch**: `001-merge-workflows` -**Created**: 2025-10-02 -**Status**: Draft -**Input**: User description: "Merge ci.yml into workflow.yml, so that we can deduplicate and two workflows and have less workflows in the repos that use this process. When the pr is created, we do want publish to run, but its got logic to not publish, unless the pull request has a 'preview' label. When merged, the full pipeline should run. When there are failures in tests, it should continue working as it is (completing code coverage and test result summarization). A repo will NEVER only need ci functionality. Check the Template-PSModule's workflow to see how its currently configured for module repos. We want to basically remove the need for the nightly run pipeline, and update the main process workflow with a schedule and a workflow dispatch. When its running in this mode, we do not want the publish steps (module and docs) to run." - -## Execution Flow (main) - -1. βœ… Parse user description from Input -2. βœ… Extract key concepts from description - - Merge two workflow files (CI.yml and workflow.yml) - - Support three execution modes: PR validation, merge/publish, scheduled testing - - Maintain existing failure handling behavior - - Eliminate Nightly-Run.yml from module repositories -3. βœ… Generate Functional Requirements - - All requirements are testable through workflow execution -4. βœ… Identify Key Entities - - Workflow triggers and execution contexts -5. βœ… Run Review Checklist - - No implementation details included - - All requirements clear and testable - ---- - -## ⚑ Quick Guidelines - -- βœ… Focus on WHAT users need and WHY -- ❌ Avoid HOW to implement (no tech stack, APIs, code structure) -- πŸ‘₯ Written for business stakeholders, not developers - -### Section Requirements - -- **Mandatory sections**: Must be completed for every feature -- **Optional sections**: Include only when relevant to the feature -- When a section doesn't apply, remove it entirely (don't leave as "N/A") - ---- - -## Review & Acceptance Checklist - -*GATE: Automated checks run during main() execution* - -### 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] Scope is clearly bounded -- [x] Dependencies and assumptions identified - ---- - -## Execution Status - -*Updated by main() during processing* - -- [x] User description parsed -- [x] Key concepts extracted -- [x] Ambiguities marked (none found) -- [x] User scenarios defined -- [x] Requirements generated -- [x] Entities identified -- [x] Review checklist passed From 606c37deff388a2d4955e74c6d28073482c804d0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug <marstor@hotmail.com> Date: Thu, 2 Oct 2025 09:17:36 +0200 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Refactor=20templa?= =?UTF-8?q?tes=20to=20use=20tables=20for=20improved=20clarity=20and=20cons?= =?UTF-8?q?istency=20in=20technical=20and=20functional=20requirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .specify/templates/plan-template.md | 20 ++++++----- .specify/templates/spec-template.md | 56 ++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/.specify/templates/plan-template.md b/.specify/templates/plan-template.md index f2d4f9aa..b488257f 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -35,15 +35,17 @@ ## Technical Context -**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] -**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] -**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] -**Testing**: [e.g., pytest, XCTest, cargo test or NEEDS CLARIFICATION] -**Target Platform**: [e.g., Linux server, iOS 15+, Wasm or NEEDS CLARIFICATION] -**Project Type**: [single/web/mobile - determines source structure] -**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] -**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] -**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] +| Aspect | Details | +|--------|---------| +| **Language/Version** | [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] | +| **Primary Dependencies** | [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] | +| **Storage** | [if applicable, e.g., PostgreSQL, CoreData, files or N/A] | +| **Testing** | [e.g., pytest, XCTest, cargo test or NEEDS CLARIFICATION] | +| **Target Platform** | [e.g., Linux server, iOS 15+, Wasm or NEEDS CLARIFICATION] | +| **Project Type** | [single/web/mobile - determines source structure] | +| **Performance Goals** | [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] | +| **Constraints** | [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] | +| **Scale/Scope** | [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] | ## Constitution Check diff --git a/.specify/templates/spec-template.md b/.specify/templates/spec-template.md index df60a7ea..47264a60 100644 --- a/.specify/templates/spec-template.md +++ b/.specify/templates/spec-template.md @@ -20,21 +20,53 @@ ### Functional Requirements -- **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"] -- **FR-002**: System MUST [specific capability, e.g., "validate email addresses"] -- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"] -- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"] -- **FR-005**: System MUST [behavior, e.g., "log all security events"] - -Example of marking unclear requirements: - -- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?] -- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified] +| ID | Requirement | +|----|-------------| +| **FR-001** | System MUST [specific capability, e.g., "allow users to create accounts"] | +| **FR-002** | System MUST [specific capability, e.g., "validate email addresses"] | +| **FR-003** | Users MUST be able to [key interaction, e.g., "reset their password"] | +| **FR-004** | System MUST [data requirement, e.g., "persist user preferences"] | +| **FR-005** | System MUST [behavior, e.g., "log all security events"] | +| **FR-006** | System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?] | +| **FR-007** | System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified] | + +### Non-Functional Requirements + +| ID | Requirement | +|----|-------------| +| **NFR-001** | System MUST respond within [specific time, e.g., "500ms for 95th percentile"] | +| **NFR-002** | System MUST handle [specific load, e.g., "1000 concurrent users"] | +| **NFR-003** | System MUST maintain [availability target, e.g., "99.9% uptime"] | +| **NFR-004** | System MUST scale to [capacity limit, e.g., "10,000 transactions per second"] | +| **NFR-005** | System MUST recover within [time period, e.g., "5 minutes after failure"] | +| **NFR-006** | System MUST encrypt data [NEEDS CLARIFICATION: encryption scope not specified - at rest, in transit, both?] | +| **NFR-007** | System MUST maintain audit logs for [NEEDS CLARIFICATION: retention period not specified] | + +### Quality Attributes Addressed + +| Attribute | Target Metric | +|-----------|---------------| +| **Performance** | [e.g., "Response time < 200ms", "Throughput > 5000 TPS"] | +| **Scalability** | [e.g., "Support 100,000 concurrent users", "Linear scaling to 10 nodes"] | +| **Availability** | [e.g., "99.95% uptime", "Max 4 hours downtime per year"] | +| **Reliability** | [e.g., "MTBF > 720 hours", "Error rate < 0.01%"] | +| **Security** | [e.g., "OWASP Top 10 compliant", "SOC 2 Type II certified"] | +| **Maintainability** | [e.g., "Code coverage > 80%", "Cyclomatic complexity < 10"] | +| **Usability** | [e.g., "Task completion time < 2 minutes", "User satisfaction > 4.5/5"] | + +### Constraints *(include if applicable)* + +| Constraint | Description | +|------------|-------------| +| **[Constraint 1]** | [Limitation or restriction, e.g., "Must run on Windows Server 2019+"] | +| **[Constraint 2]** | [Compliance requirement, e.g., "Must comply with GDPR"] | ### Key Entities *(include if feature involves data)* -- **[Entity 1]**: [What it represents, key attributes without implementation] -- **[Entity 2]**: [What it represents, relationships to other entities] +| Entity | Description | +|--------|-------------| +| **[Entity 1]** | [What it represents, key attributes without implementation] | +| **[Entity 2]** | [What it represents, relationships to other entities] | ---