From 5a91cf03830da93d8aed3751a3d23fd5da76c88c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 13:24:30 +0200 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=93=96[Feature]:=20Add=20unified=20CI?= =?UTF-8?q?=20and=20release=20workflow=20specification?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- specs/001-merge-ci-release-workflows/spec.md | 124 +++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 specs/001-merge-ci-release-workflows/spec.md diff --git a/specs/001-merge-ci-release-workflows/spec.md b/specs/001-merge-ci-release-workflows/spec.md new file mode 100644 index 00000000..606898e4 --- /dev/null +++ b/specs/001-merge-ci-release-workflows/spec.md @@ -0,0 +1,124 @@ +# Feature Specification: Unified CI and Release Workflow + +## User Scenarios & Testing *(mandatory)* + +### Primary User Story + +As a PowerShell module maintainer managing multiple repositories, I need a single workflow configuration that automatically runs tests on pull requests and publishes releases when changes are merged to the main branch. This unified workflow eliminates the need to maintain two separate workflow files (CI.yml and workflow.yml) across all repositories, reducing configuration complexity and ensuring consistency. + +### Acceptance Scenarios + +1. **Given** a pull request is opened or updated, **When** the workflow runs, **Then** it MUST execute all CI tests without attempting any release operations +2. **Given** a pull request is merged to the main branch, **When** the workflow runs, **Then** it MUST execute CI tests and proceed to release/publish operations if tests pass +3. **Given** changes are pushed directly to the main branch (bypass PR), **When** the workflow runs, **Then** it MUST execute both CI tests and release operations +4. **Given** CI tests fail on a PR, **When** the workflow completes, **Then** it MUST report failure status and NOT proceed to any release operations +5. **Given** CI tests fail on main branch, **When** the workflow completes, **Then** it MUST report failure and halt before release operations +6. **Given** a repository adopts this unified workflow, **When** migration is complete, **Then** maintainers MUST be able to remove separate CI.yml and workflow.yml files without losing functionality + +### Edge Cases + +- What happens when a workflow is manually triggered (workflow_dispatch)? +- How does the workflow handle concurrent runs when multiple PRs are merged rapidly? +- What happens if release operations fail after CI tests pass on main branch? +- How does the workflow distinguish between testing-only and release-required contexts? +- What happens when a repository has custom test configurations or matrix strategies? + +## Requirements *(mandatory)* + +### Functional Requirements + +| ID | Requirement | +|----|-------------| +| **FR-001** | Workflow MUST trigger on pull request events (opened, synchronized, reopened) | +| **FR-002** | Workflow MUST trigger on push events to the main branch | +| **FR-003** | Workflow MUST execute CI test suite for all trigger events | +| **FR-004** | Workflow MUST conditionally execute release operations only on main branch pushes | +| **FR-005** | Workflow MUST skip release operations when running on pull request events | +| **FR-006** | Workflow MUST report test results as PR status checks | +| **FR-007** | Workflow MUST fail fast and halt execution if CI tests fail | +| **FR-008** | Workflow MUST publish module releases to [NEEDS CLARIFICATION: target registry not specified - PowerShell Gallery, private feed, both?] | +| **FR-009** | Workflow MUST create GitHub releases with [NEEDS CLARIFICATION: versioning strategy not specified - semantic versioning, date-based, manual tags?] | +| **FR-010** | Workflow MUST be compatible with existing repository structures used in PSModule repositories | +| **FR-011** | Workflow MUST support manual triggering (workflow_dispatch) with [NEEDS CLARIFICATION: should manual triggers allow release operations, or tests only?] | +| **FR-012** | Workflow MUST handle authentication for [NEEDS CLARIFICATION: authentication targets not specified - PowerShell Gallery API keys, GitHub tokens, other credentials?] | + +### Non-Functional Requirements + +| ID | Requirement | +|----|-------------| +| **NFR-001** | Workflow MUST complete CI test phase within reasonable time limits [NEEDS CLARIFICATION: acceptable time limits not specified] | +| **NFR-002** | Workflow MUST be maintainable as a single source of truth across multiple repositories | +| **NFR-003** | Workflow MUST provide clear logging to distinguish CI and release phases | +| **NFR-004** | Workflow MUST be idempotent for release operations (safe to re-run without duplicate publishes) | +| **NFR-005** | Workflow configuration MUST be simple enough for module maintainers to understand and customize | +| **NFR-006** | Workflow MUST minimize redundant work when transitioning from PR to main branch merge | + +### Quality Attributes Addressed + +| Attribute | Target Metric | +|-----------|---------------| +| **Maintainability** | Single workflow file replaces two separate files; changes apply to all repositories via template updates | +| **Reliability** | Consistent behavior across all trigger scenarios; fail-safe design prevents accidental releases | +| **Usability** | Clear phase separation; easy to understand which operations run in which context | +| **Efficiency** | Reduced configuration overhead; faster onboarding for new repositories | + +### Constraints + +| Constraint | Description | +|------------|-------------| +| **GitHub Actions** | Must run on GitHub Actions platform using composite actions or reusable workflows | +| **PowerShell Module Structure** | Must work with PSModule repository structure conventions | +| **Backward Compatibility** | Must not break existing CI or release behaviors when migrating from separate workflows | +| **Existing Actions** | Must leverage existing PSModule GitHub actions (PSModule/GitHub-Script@v1, PSModule/Install-PSModuleHelpers@v1) | + +### Key Entities + +| Entity | Description | +|--------|-------------| +| **Workflow Configuration** | Single YAML file defining triggers, jobs, and conditional logic for CI and release phases | +| **CI Phase** | Test execution, validation, and quality checks that run on all events | +| **Release Phase** | Module publishing, GitHub release creation, and post-release operations that run only on main branch | +| **Trigger Context** | Runtime information determining whether workflow runs in PR mode or release mode | +| **Test Results** | Output from CI phase determining whether release phase can proceed | + +--- + +**Feature Branch**: `001-merge-ci-release-workflows` +**Created**: 2025-10-02 +**Status**: Draft +**Input**: User description: "As a PowerShell module maintainer managing multiple repositories, I need a single workflow configuration that handles both continuous integration testing on pull requests and automated release publishing on merges to the main branch. This eliminates the maintenance burden of keeping two separate workflow files (CI.yml and workflow.yml) synchronized across all my module repositories, reducing configuration complexity and the risk of inconsistencies." + +## 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 + +- [ ] 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 +- [x] User scenarios defined +- [x] Requirements generated +- [x] Entities identified +- [x] Review checklist passed (with clarifications needed) + +--- From 2b126f568cf9833709e008d7260447469737b112 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 13:34:17 +0200 Subject: [PATCH 2/6] feat: Complete implementation plan for unified CI and release workflow - Analyzed existing workflow.yml and CI.yml to understand differences - Designed conditional execution logic for intelligent CI/Release mode switching - Created comprehensive data model for workflow state transitions - Documented workflow API contract maintaining backward compatibility - Created migration guide (quickstart.md) for consuming repositories - Updated copilot instructions with recent changes Constitutional compliance: - Workflow-First Design: Enhances existing reusable workflow - TDD: Test scenarios documented before implementation - Platform Independence: No platform-specific changes - Quality Gates: Existing gates preserved - Semantic Versioning: Breaking change requires v5.0.0 Breaking Change: CI.yml deprecated; unified workflow.yml handles both CI and release --- .github/copilot-instructions.md | 11 +- .../contracts/workflow-api.md | 362 ++++++++++++++ .../data-model.md | 309 ++++++++++++ specs/001-merge-ci-release-workflows/plan.md | 458 ++++++++++++++++++ .../quickstart.md | 410 ++++++++++++++++ .../research.md | 286 +++++++++++ 6 files changed, 1832 insertions(+), 4 deletions(-) create mode 100644 specs/001-merge-ci-release-workflows/contracts/workflow-api.md create mode 100644 specs/001-merge-ci-release-workflows/data-model.md create mode 100644 specs/001-merge-ci-release-workflows/plan.md create mode 100644 specs/001-merge-ci-release-workflows/quickstart.md create mode 100644 specs/001-merge-ci-release-workflows/research.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 3b5a54b5..197f99b0 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,28 +1,31 @@ # Process-PSModule Development Guidelines -Auto-generated from all feature plans. Last updated: 2025-10-01 +Auto-generated from all feature plans. Last updated: 2025-10-02 ## Active Technologies -- PowerShell 7.4+ (GitHub Actions composite actions) + PSModule/GitHub-Script@v1, PSModule/Install-PSModuleHelpers@v1 (001-building-on-this) +- PowerShell 7.4+ (GitHub Actions composite actions) + PSModule/GitHub-Script@v1, PSModule/Install-PSModuleHelpers@v1, PSModule/Publish-PSModule@v2 (001-merge-ci-release-workflows) ## Project Structure ```plaintext -src/ +.github/workflows/ +specs/ tests/ ``` ## Commands -Add commands for PowerShell 7.4+ (GitHub Actions composite actions) +Workflow development for PowerShell 7.4+ (GitHub Actions composite actions) ## Code Style PowerShell 7.4+ (GitHub Actions composite actions): Follow standard conventions +GitHub Actions YAML: Follow conditional execution patterns ## Recent Changes +- 001-merge-ci-release-workflows: Unified workflow.yml handles CI and release with conditional execution; CI.yml deprecated (v5.0.0 breaking change) - 001-building-on-this: Added PowerShell 7.4+ (GitHub Actions composite actions) + PSModule/GitHub-Script@v1, PSModule/Install-PSModuleHelpers@v1 diff --git a/specs/001-merge-ci-release-workflows/contracts/workflow-api.md b/specs/001-merge-ci-release-workflows/contracts/workflow-api.md new file mode 100644 index 00000000..09efee6b --- /dev/null +++ b/specs/001-merge-ci-release-workflows/contracts/workflow-api.md @@ -0,0 +1,362 @@ +# Workflow API Contract: Unified CI and Release Workflow + +**Feature**: 001-merge-ci-release-workflows +**Date**: 2025-10-02 +**Workflow File**: `.github/workflows/workflow.yml` + +## Contract Overview + +The unified workflow maintains the same API surface as the existing workflow.yml to ensure backward compatibility with consuming repositories. + +## Workflow Trigger + +```yaml +on: + workflow_call: + # Unchanged from v4.x +``` + +**Contract**: Workflow is callable from consuming repository workflows using `uses:` syntax. + +**Example Consumer Usage**: +```yaml +name: Process-PSModule + +on: + pull_request: + branches: [main] + types: [closed, opened, reopened, synchronize, labeled] + push: + branches: [main] + workflow_dispatch: + +jobs: + Process-PSModule: + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v5 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +## Inputs + +All inputs remain unchanged from workflow.yml v4.x: + +### Input: Name +- **Type**: `string` +- **Description**: The name of the module to process. Scripts default to the repository name if nothing is specified. +- **Required**: `false` +- **Default**: Repository name (auto-detected) + +### Input: SettingsPath +- **Type**: `string` +- **Description**: The path to the settings file. Settings in the settings file take precedence over the action inputs. +- **Required**: `false` +- **Default**: `.github/PSModule.yml` + +### Input: Debug +- **Type**: `boolean` +- **Description**: Enable debug output. +- **Required**: `false` +- **Default**: `false` + +### Input: Verbose +- **Type**: `boolean` +- **Description**: Enable verbose output. +- **Required**: `false` +- **Default**: `false` + +### Input: Version +- **Type**: `string` +- **Description**: Specifies the version of the GitHub module to be installed. The value must be an exact version. +- **Required**: `false` +- **Default**: `''` (latest stable) + +### Input: Prerelease +- **Type**: `boolean` +- **Description**: Whether to use a prerelease version of the 'GitHub' module. +- **Required**: `false` +- **Default**: `false` + +### Input: WorkingDirectory +- **Type**: `string` +- **Description**: The path to the root of the repo. +- **Required**: `false` +- **Default**: `'.'` (repository root) + +## Secrets + +All secrets remain unchanged from workflow.yml v4.x: + +### Secret: APIKey +- **Description**: The API key for the PowerShell Gallery. +- **Required**: `true` (for Publish-Module job execution) +- **Used By**: Publish-Module job +- **Note**: Required even in CI-only mode (job is skipped but secret must be defined) + +### Secret: TEST_APP_ENT_CLIENT_ID +- **Description**: The client ID of an Enterprise GitHub App for running tests. +- **Required**: `false` +- **Used By**: Test-ModuleLocal job (if Enterprise App tests are enabled) + +### Secret: TEST_APP_ENT_PRIVATE_KEY +- **Description**: The private key of an Enterprise GitHub App for running tests. +- **Required**: `false` +- **Used By**: Test-ModuleLocal job (if Enterprise App tests are enabled) + +### Secret: TEST_APP_ORG_CLIENT_ID +- **Description**: The client ID of an Organization GitHub App for running tests. +- **Required**: `false` +- **Used By**: Test-ModuleLocal job (if Organization App tests are enabled) + +### Secret: TEST_APP_ORG_PRIVATE_KEY +- **Description**: The private key of an Organization GitHub App for running tests. +- **Required**: `false` +- **Used By**: Test-ModuleLocal job (if Organization App tests are enabled) + +### Secret: TEST_USER_ORG_FG_PAT +- **Description**: The fine-grained personal access token with org access for running tests. +- **Required**: `false` +- **Used By**: Test-ModuleLocal job (if org-level tests are enabled) + +### Secret: TEST_USER_USER_FG_PAT +- **Description**: The fine-grained personal access token with user account access for running tests. +- **Required**: `false` +- **Used By**: Test-ModuleLocal job (if user-level tests are enabled) + +### Secret: TEST_USER_PAT +- **Description**: The classic personal access token for running tests. +- **Required**: `false` +- **Used By**: Test-ModuleLocal job (if PAT-based tests are enabled) + +## Outputs + +The workflow does not define explicit outputs. Results are communicated through: + +1. **Workflow Artifacts**: + - `module`: Built module artifact (from Build-Module job) + - `site`: Documentation site artifact (from Build-Site job) + - `test-results`: Test result files (from test jobs) + - `code-coverage`: Code coverage reports (from Get-CodeCoverage job) + +2. **GitHub Releases**: Created by Publish-Module job (release mode only) + +3. **GitHub Pages**: Deployed by Publish-Site job (release mode only) + +4. **Workflow Status**: Success/failure status reported to PR and commit status checks + +## Permissions + +The workflow requires the following permissions: + +```yaml +permissions: + contents: write # to checkout the repo and create releases on the repo + pull-requests: write # to write comments to PRs + statuses: write # to update the status of the workflow from linter + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source +``` + +**Note**: These permissions are required for full functionality (CI + Release mode). In CI-only mode, `pages` and `id-token` permissions are unused but do not cause issues. + +## Job Execution Contract + +### Always Executed Jobs + +The following jobs execute in all modes (CI-only and CI + Release): + +1. **Get-Settings**: Load and parse module settings +2. **Build-Module**: Compile module from source +3. **Build-Docs**: Generate module documentation +4. **Build-Site**: Build documentation site +5. **Test-SourceCode**: Matrix test source code (multiple OS) +6. **Lint-SourceCode**: Matrix lint source code (multiple OS) +7. **Test-Module**: Test built module integrity +8. **BeforeAll-ModuleLocal**: Setup external test resources (if tests/BeforeAll.ps1 exists) +9. **Test-ModuleLocal**: Matrix test module functionality (ubuntu, windows, macos) +10. **AfterAll-ModuleLocal**: Teardown external test resources (if tests/AfterAll.ps1 exists) +11. **Get-TestResults**: Aggregate and validate test results +12. **Get-CodeCoverage**: Analyze code coverage + +### Conditionally Executed Jobs + +The following jobs execute only in CI + Release mode: + +13. **Publish-Module**: Publish module to PowerShell Gallery + - **Condition**: Tests pass AND (merged PR OR push to default branch) + +14. **Publish-Site**: Deploy documentation to GitHub Pages + - **Condition**: Tests pass AND Build-Site succeeds AND (merged PR OR push to default branch) + +## Conditional Execution Logic + +### Publish-Module Condition + +```yaml +if: | + needs.Get-Settings.result == 'success' && + needs.Get-TestResults.result == 'success' && + needs.Get-CodeCoverage.result == 'success' && + !cancelled() && + ( + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || + (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) + ) +``` + +**Publishes When**: +- All tests pass (Get-TestResults, Get-CodeCoverage success) +- Workflow not cancelled +- **Either**: + - Pull request merged to default branch, **OR** + - Direct push to default branch + +**Skips When**: +- Tests fail +- Workflow cancelled +- Unmerged pull request +- Manual trigger (`workflow_dispatch`) +- Scheduled run (`schedule`) +- Push to non-default branch + +### Publish-Site Condition + +```yaml +if: | + needs.Get-Settings.result == 'success' && + needs.Get-TestResults.result == 'success' && + needs.Get-CodeCoverage.result == 'success' && + needs.Build-Site.result == 'success' && + !cancelled() && + ( + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || + (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) + ) +``` + +**Publishes When**: Same as Publish-Module, plus Build-Site must succeed + +## Behavioral Contract by Trigger Type + +### Trigger: Pull Request (Opened/Synchronized/Reopened) + +**Event**: `github.event_name == 'pull_request'` AND `github.event.pull_request.merged == false` + +**Behavior**: +- ✅ Execute all CI jobs (build, test, lint) +- ❌ Skip Publish-Module +- ❌ Skip Publish-Site +- ✅ Report test results as PR status checks +- ✅ Comment on PR with test/coverage results + +**Exit**: Workflow completes after test results + +### Trigger: Pull Request (Merged) + +**Event**: `github.event_name == 'pull_request'` AND `github.event.pull_request.merged == true` + +**Behavior**: +- ✅ Execute all CI jobs (build, test, lint) +- ✅ Execute Publish-Module (if tests pass) +- ✅ Execute Publish-Site (if tests pass and Build-Site succeeds) +- ✅ Create GitHub release +- ✅ Deploy documentation to GitHub Pages + +**Exit**: Workflow completes after successful publish + +### Trigger: Push to Default Branch + +**Event**: `github.event_name == 'push'` AND `github.ref == 'refs/heads/main'` + +**Behavior**: Same as merged pull request +- ✅ Execute all CI jobs +- ✅ Execute Publish-Module (if tests pass) +- ✅ Execute Publish-Site (if tests pass) + +**Note**: Direct pushes bypass PR validation; use with caution + +### Trigger: Push to Non-Default Branch + +**Event**: `github.event_name == 'push'` AND `github.ref != 'refs/heads/main'` + +**Behavior**: +- ✅ Execute all CI jobs +- ❌ Skip Publish-Module +- ❌ Skip Publish-Site + +**Use Case**: Feature branch validation without PR + +### Trigger: Manual (workflow_dispatch) + +**Event**: `github.event_name == 'workflow_dispatch'` + +**Behavior**: +- ✅ Execute all CI jobs +- ❌ Skip Publish-Module +- ❌ Skip Publish-Site + +**Use Case**: On-demand validation without publishing + +### Trigger: Scheduled (schedule) + +**Event**: `github.event_name == 'schedule'` + +**Behavior**: +- ✅ Execute all CI jobs +- ❌ Skip Publish-Module +- ❌ Skip Publish-Site + +**Use Case**: Nightly regression testing + +## Breaking Changes from v4.x + +### For Consuming Repositories Using workflow.yml + +**Impact**: ✅ **None** - Existing behavior preserved + +**Changes Required**: None (optional: review trigger conditions in consuming repo workflow) + +### For Consuming Repositories Using CI.yml + +**Impact**: ⚠️ **Deprecation Warning** - CI.yml marked deprecated + +**Changes Required**: Migrate to workflow.yml during v5.x lifecycle + +**Migration Path**: +1. Update consuming repository workflow to call workflow.yml instead of CI.yml +2. Test both PR and merge workflows +3. Remove CI.yml reference from consuming repository + +### For Process-PSModule Framework + +**Impact**: 🌟 **Breaking Change** - Major version bump (v5.0.0) + +**Changes**: +- CI.yml deprecated (removed in v6.0.0) +- Unified workflow.yml handles all scenarios +- New conditional execution logic + +## Validation Test Cases + +Consuming repositories should validate these scenarios after migration: + +1. ✅ **PR Opened**: CI runs, no publish +2. ✅ **PR Synchronized**: CI runs, no publish +3. ✅ **PR Merged**: CI runs, publish succeeds +4. ✅ **Direct Push to Main**: CI runs, publish succeeds +5. ✅ **Push to Feature Branch**: CI runs (if configured), no publish +6. ✅ **Manual Trigger**: CI runs, no publish +7. ✅ **Test Failure**: Workflow fails, no publish +8. ✅ **Coverage Below Threshold**: Workflow fails, no publish + +## Support and Compatibility + +| Process-PSModule Version | Unified Workflow | CI.yml Support | API Breaking Changes | +|-------------------------|------------------|----------------|---------------------| +| v4.x (current) | ❌ No | ✅ Yes | N/A | +| v5.0 (this feature) | ✅ Yes | ⚠️ Deprecated | No (for workflow.yml users) | +| v6.0 (future) | ✅ Yes | ❌ Removed | Yes (CI.yml removed) | + +## Conclusion + +The unified workflow maintains API compatibility with workflow.yml v4.x while adding intelligent conditional execution. Consuming repositories using workflow.yml continue working without changes. Consumers using CI.yml should migrate during the v5.x support period. diff --git a/specs/001-merge-ci-release-workflows/data-model.md b/specs/001-merge-ci-release-workflows/data-model.md new file mode 100644 index 00000000..b9a050a4 --- /dev/null +++ b/specs/001-merge-ci-release-workflows/data-model.md @@ -0,0 +1,309 @@ +# Data Model: Unified CI and Release Workflow + +**Feature**: 001-merge-ci-release-workflows +**Date**: 2025-10-02 + +## Workflow Execution Modes + +The unified workflow operates in one of two execution modes, determined dynamically at runtime based on trigger context. + +### Mode 1: CI-Only (Test-Only Execution) + +**Purpose**: Validate code changes without publishing releases + +**Trigger Conditions**: +- Pull request opened, synchronized, or reopened (not merged) +- Manual workflow trigger (`workflow_dispatch`) +- Scheduled workflow runs (`schedule`) +- Push to non-default branch + +**Job Execution**: +``` +Get-Settings +├── Build-Module +│ ├── Build-Docs +│ ├── Build-Site +│ ├── Test-SourceCode (matrix: multiple OS) +│ ├── Lint-SourceCode (matrix: multiple OS) +│ ├── Test-Module +│ ├── BeforeAll-ModuleLocal +│ ├── Test-ModuleLocal (matrix: ubuntu, windows, macos) +│ ├── AfterAll-ModuleLocal +│ ├── Get-TestResults +│ └── Get-CodeCoverage +``` + +**Skipped Jobs**: +- Publish-Module +- Publish-Site + +**Permissions Required**: +- `contents: write` (for checkout and tags) +- `pull-requests: write` (for PR comments) +- `statuses: write` (for linter status) +- Note: Publish permissions not required but maintained for consistency + +**Exit Criteria**: +- All test jobs complete (success or failure) +- Test results reported +- Code coverage analyzed +- Workflow exits without release operations + +### Mode 2: CI + Release (Full Pipeline Execution) + +**Purpose**: Validate code changes and publish releases + +**Trigger Conditions**: +- Pull request merged to default branch (`github.event.pull_request.merged == true`) +- Direct push to default branch (`github.ref == refs/heads/main`) + +**Job Execution**: +``` +Get-Settings +├── Build-Module +│ ├── Build-Docs +│ ├── Build-Site +│ ├── Test-SourceCode (matrix: multiple OS) +│ ├── Lint-SourceCode (matrix: multiple OS) +│ ├── Test-Module +│ ├── BeforeAll-ModuleLocal +│ ├── Test-ModuleLocal (matrix: ubuntu, windows, macos) +│ ├── AfterAll-ModuleLocal +│ ├── Get-TestResults +│ ├── Get-CodeCoverage +│ ├── Publish-Module ← EXECUTES +│ └── Publish-Site ← EXECUTES +``` + +**Skipped Jobs**: None (all jobs execute if tests pass) + +**Permissions Required**: +- `contents: write` (for checkout, tags, and GitHub releases) +- `pull-requests: write` (for PR comments) +- `statuses: write` (for linter status) +- `pages: write` (for GitHub Pages deployment) +- `id-token: write` (for deployment verification) + +**Exit Criteria**: +- All test jobs complete successfully +- Module published to PowerShell Gallery +- Documentation site deployed to GitHub Pages +- GitHub release created with artifacts + +## Workflow State Transitions + +``` +[Workflow Triggered] + | + v +[Get-Settings] → Determine configuration + | + v +[Build & Test Jobs] → Execute always (both modes) + | + v +[Test Results Check] + | + ├─ Tests Failed → Exit (no publishing) + | + └─ Tests Passed + | + v + [Evaluate Trigger Context] + | + ├─ Unmerged PR / Manual / Scheduled → Skip Publishing (CI-Only Mode) + | + └─ Merged PR / Main Push → Execute Publishing (CI + Release Mode) + | + v + [Publish-Module & Publish-Site] + | + v + [Release Complete] +``` + +## Conditional Logic Entities + +### Entity: TriggerContext + +**Purpose**: Encapsulates GitHub event information used for conditional execution + +**Attributes**: +- `event_name`: GitHub event type (pull_request, push, workflow_dispatch, schedule) +- `is_pull_request`: Boolean indicating PR event +- `is_merged`: Boolean indicating merged PR (only relevant for pull_request events) +- `ref`: Git reference (branch/tag) for push events +- `default_branch`: Repository default branch name + +**Derived Properties**: +- `is_ci_only_mode`: `!is_merged || event_name not in [pull_request, push]` +- `is_release_mode`: `(is_pull_request && is_merged) || (event_name == push && ref == default_branch)` + +**Example Values**: + +| Scenario | event_name | is_pull_request | is_merged | ref | is_release_mode | +|----------|------------|----------------|-----------|-----|----------------| +| PR opened | pull_request | true | false | N/A | false (CI-only) | +| PR merged | pull_request | true | true | N/A | true (Release) | +| Push to main | push | false | N/A | refs/heads/main | true (Release) | +| Push to feature | push | false | N/A | refs/heads/feature-x | false (CI-only) | +| Manual trigger | workflow_dispatch | false | N/A | N/A | false (CI-only) | +| Scheduled run | schedule | false | N/A | N/A | false (CI-only) | + +### Entity: JobExecutionPlan + +**Purpose**: Defines which jobs execute based on trigger context and test results + +**Attributes**: +- `trigger_context`: TriggerContext instance +- `test_results_passed`: Boolean from Get-TestResults job +- `code_coverage_passed`: Boolean from Get-CodeCoverage job +- `build_site_passed`: Boolean from Build-Site job +- `workflow_cancelled`: Boolean indicating workflow cancellation + +**Methods**: +- `should_publish_module()`: Returns true if Publish-Module should execute +- `should_publish_site()`: Returns true if Publish-Site should execute + +**Logic**: + +```yaml +should_publish_module(): + return ( + test_results_passed && + code_coverage_passed && + !workflow_cancelled && + trigger_context.is_release_mode + ) + +should_publish_site(): + return ( + test_results_passed && + code_coverage_passed && + build_site_passed && + !workflow_cancelled && + trigger_context.is_release_mode + ) +``` + +### Entity: WorkflowConfiguration + +**Purpose**: Settings that control workflow behavior (from .github/PSModule.yml) + +**Attributes**: +- `skip_build`: Boolean to skip Build-Module job +- `skip_tests`: Boolean to skip test jobs +- `skip_publish`: Boolean to skip publish jobs (overrides trigger context) +- `auto_patching`: Boolean for automatic patch version bumps +- `prerelease_increment`: Boolean for incremental prerelease versioning + +**Usage**: Allows consuming repositories to override default behavior + +## Migration State Model + +### Repository Migration States + +**State 1: Legacy (Using CI.yml)** +- Repository has `.github/workflows/CI.yml` for PR validation +- Repository has `.github/workflows/Process-PSModule.yml` calling workflow.yml for releases +- Two separate workflow files to maintain + +**State 2: Transitional (Adopting Unified)** +- Repository updates `.github/workflows/Process-PSModule.yml` to use workflow.yml for all events +- CI.yml remains but is unused (safety net) +- Single workflow handles CI and release + +**State 3: Unified (Complete Migration)** +- Repository removes `.github/workflows/CI.yml` entirely +- Single `.github/workflows/Process-PSModule.yml` handles all events +- Optimal state: one workflow file to maintain + +### Migration Validation + +**Validation Checklist**: +1. ✅ PR opened → CI tests run, no publish +2. ✅ PR merged → CI tests run, publish succeeds +3. ✅ Direct push to main → CI tests run, publish succeeds +4. ✅ Manual trigger → CI tests run, no publish +5. ✅ Feature branch push → No workflow trigger (expected) + +## Backward Compatibility + +### Existing workflow.yml Consumers + +**Impact**: Minimal - existing behavior preserved + +**Changes Required**: None immediately + +**Recommended Updates**: +1. Review trigger conditions in consuming repository workflows +2. Update documentation referencing CI.yml +3. Plan removal of CI.yml references + +### Existing CI.yml Consumers + +**Impact**: CI.yml marked deprecated; functionality unchanged + +**Changes Required**: Migrate to workflow.yml during v5.x timeframe + +**Migration Path**: +1. Update workflow file to call workflow.yml instead of CI.yml +2. Test PR and release workflows +3. Remove CI.yml reference after validation +4. Remove local CI.yml file (optional during v5.x) + +## Version Compatibility Matrix + +| Process-PSModule Version | Unified Workflow | CI.yml Support | Breaking Changes | +|-------------------------|------------------|----------------|-----------------| +| v4.x (current) | ❌ No | ✅ Yes | N/A | +| v5.0 (this feature) | ✅ Yes | ⚠️ Deprecated | Yes - CI.yml deprecated | +| v6.0 (future) | ✅ Yes | ❌ Removed | Yes - CI.yml removed entirely | + +## Data Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────┐ +│ GitHub Trigger Event │ +│ (PR opened/merged, push, workflow_dispatch, schedule) │ +└────────────────────┬────────────────────────────────────────┘ + │ + v +┌─────────────────────────────────────────────────────────────┐ +│ Get-Settings Job │ +│ - Load .github/PSModule.yml │ +│ - Parse configuration │ +│ - Output settings JSON │ +└────────────────────┬────────────────────────────────────────┘ + │ + v +┌─────────────────────────────────────────────────────────────┐ +│ Build & Test Phase (Always Executes) │ +│ - Build-Module, Build-Docs, Build-Site │ +│ - Test-SourceCode, Lint-SourceCode, Test-Module │ +│ - Test-ModuleLocal (matrix: 3 OS) │ +│ - Get-TestResults, Get-CodeCoverage │ +└────────────────────┬────────────────────────────────────────┘ + │ + v +┌─────────────────────────────────────────────────────────────┐ +│ Conditional Evaluation │ +│ - Check: Tests passed? │ +│ - Check: Trigger context (merged/push to main?) │ +│ - Check: Workflow not cancelled? │ +└─────┬──────────────────────────────────┬────────────────────┘ + │ │ + v v +┌─────────────────┐ ┌──────────────────────────┐ +│ CI-Only Mode │ │ CI + Release Mode │ +│ Skip Publishing │ │ Execute Publishing │ +│ Exit │ │ │ +└─────────────────┘ │ - Publish-Module │ + │ - Publish-Site │ + │ - Create GitHub Release │ + └──────────────────────────┘ +``` + +## Conclusion + +The workflow state model is deterministic and based on observable trigger context. The conditional logic ensures safe, predictable behavior across all trigger scenarios while maintaining a single workflow file. diff --git a/specs/001-merge-ci-release-workflows/plan.md b/specs/001-merge-ci-release-workflows/plan.md new file mode 100644 index 00000000..0c397924 --- /dev/null +++ b/specs/001-merge-ci-release-workflows/plan.md @@ -0,0 +1,458 @@ +# Implementation Plan: Unified CI and Release Workflow + +**Branch**: `001-merge-ci-release-workflows` | **Date**: 2025-10-02 | **Spec**: [spec.md](./spec.md) +**Input**: Feature specification from `specs/001-merge-ci-release-workflows/spec.md` + +## Execution Flow (/plan command scope) + +1. Load feature spec from Input path + → If not found: ERROR "No feature spec at {path}" +2. Fill Technical Context (scan for NEEDS CLARIFICATION) + → Detect Project Type from file system structure or context (web=frontend+backend, mobile=app+API) + → Set Structure Decision based on project type +3. Fill the Constitution Check section based on the content of the constitution document. +4. Evaluate Constitution Check section below + → If violations exist: Document them in Complexity Tracking + → If no justification is possible: ERROR "Simplify approach first" + → Update Progress Tracking: Initial Constitution Check +5. Execute Phase 0 → research.md + → If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns" +6. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, `GEMINI.md` for Gemini CLI, `QWEN.md` for Qwen Code or `AGENTS.md` for opencode). +7. Re-evaluate Constitution Check section + → If new violations: Refactor design, return to Phase 1 + → Update Progress Tracking: Post-Design Constitution Check +8. Plan Phase 2 → Describe task generation approach (DO NOT create tasks.md) +9. STOP - Ready for /tasks command + +**IMPORTANT**: The /plan command STOPS at step 7. Phases 2-4 are executed by other commands: + +- Phase 2: /tasks command creates tasks.md +- Phase 3-4: Implementation execution (manual or via tools) + +## Summary + +This feature consolidates the separate CI (CI.yml) and release (workflow.yml) workflows into a single unified workflow that intelligently handles both continuous integration testing and automated release publishing based on trigger context. The unified workflow executes CI tests on all events (PR and main branch), but conditionally executes release operations only when changes are merged to the main branch. This breaking change eliminates maintenance overhead across all PSModule repositories by providing a single source of truth for the entire CI/CD pipeline. + +## Technical Context + +| Aspect | Details | +|--------|---------| +| **Language/Version** | PowerShell 7.4+ (GitHub Actions composite actions), YAML (GitHub Actions workflows) | +| **Primary Dependencies** | GitHub Actions, PSModule/GitHub-Script@v1, PSModule/Install-PSModuleHelpers@v1, PSModule/Publish-PSModule@v2 | +| **Storage** | GitHub Actions artifacts for module builds, test results, and code coverage data | +| **Testing** | Pester tests, PSScriptAnalyzer linting, cross-platform matrix testing (ubuntu-latest, windows-latest, macos-latest) | +| **Target Platform** | GitHub Actions runners (ubuntu-latest, windows-latest, macos-latest) | +| **Project Type** | Single project (GitHub Actions reusable workflow framework) | +| **Performance Goals** | Workflow execution time similar to current separate workflows (no performance regression) | +| **Constraints** | Must maintain backward compatibility with existing trigger patterns; must not require simultaneous updates across all consuming repositories | +| **Scale/Scope** | Affects all PSModule repositories consuming Process-PSModule workflows (~10-20 repositories); single workflow file replacing two separate files | + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +### I. Workflow-First Design (NON-NEGOTIABLE) + +- [x] Feature is implemented as reusable GitHub Actions workflow(s) + - Unified workflow.yml will remain a reusable workflow with `workflow_call` trigger +- [x] Workflows have clearly defined inputs and outputs + - Same inputs/outputs as current workflow.yml; secrets remain unchanged +- [x] Workflows follow single responsibility principle + - Single workflow handles complete CI/CD pipeline with conditional execution +- [x] Matrix strategies used for parallel execution where appropriate + - Existing matrix strategies preserved (Test-SourceCode, Test-ModuleLocal) +- [x] Workflows are independently testable via CI validation workflow + - Existing CI validation workflow pattern will be adapted for unified workflow +- [x] Logic delegated to reusable GitHub Actions (PSModule organization) + - All existing action calls preserved (PSModule/GitHub-Script@v1, etc.) +- [x] Inline PowerShell code avoided; action-based scripts used instead + - No inline PowerShell; all scripts delegated to actions +- [x] Actions referenced by specific versions/tags + - All actions use versioned references (@v1, @v2, etc.) + +### II. Test-Driven Development (NON-NEGOTIABLE) + +- [x] Tests will be written before implementation + - Test plan for conditional execution logic before workflow modifications +- [x] Initial tests will fail (Red phase documented) + - Validation tests will fail until conditional logic implemented +- [x] Implementation plan includes making tests pass (Green phase) + - Implementation phases documented below +- [x] Refactoring phase planned while maintaining tests + - Workflow optimization phase after initial implementation +- [x] PSScriptAnalyzer validation included + - Existing linting workflows apply to any PowerShell scripts +- [x] Manual testing documented if needed + - Manual testing required for trigger condition validation +- [x] CI validation workflow tests included + - CI validation workflow will be updated to test unified workflow + +### III. Platform Independence with Modern PowerShell + +- [x] PowerShell 7.4+ constructs used exclusively + - All PowerShell scripts target 7.4+ +- [x] Matrix testing across Linux, macOS, Windows included + - Existing Test-ModuleLocal matrix preserved (ubuntu-latest, windows-latest, macos-latest) +- [x] Platform-specific behaviors documented + - No platform-specific changes; workflow behavior platform-agnostic +- [x] Skip mechanisms justified if platform-specific tests needed + - No platform-specific skip mechanisms needed +- [x] No backward compatibility with PowerShell 5.1 required + - No 5.1 compatibility required + +### IV. Quality Gates and Observability + +- [x] Test results captured in structured JSON format + - Existing Get-TestResults job captures structured results +- [x] Code coverage measurement included + - Existing Get-CodeCoverage job preserved +- [x] Linting results captured and enforced + - Existing Lint-SourceCode job preserved +- [x] Quality gate thresholds defined + - Existing quality gates maintained +- [x] Clear error messages planned + - Conditional execution includes clear skip reasons +- [x] Debug mode support included + - Existing Debug input parameter preserved + +### V. Continuous Delivery with Semantic Versioning + +- [x] Version bump strategy documented (labels, SemVer) + - This is a Major breaking change requiring version bump to v5 +- [x] Release automation compatible with existing workflow + - Unified workflow maintains existing release automation +- [x] Documentation updates included + - README and migration guide required +- [x] GitHub Pages publishing considered if docs changes + - Documentation site will be updated with migration instructions + +## Project Structure + +### Documentation (this feature) + +```plaintext +specs/001-merge-ci-release-workflows/ +├── spec.md # Feature specification +├── plan.md # This file (implementation plan) +├── research.md # Phase 0 output (workflow analysis) +├── data-model.md # Phase 1 output (workflow state model) +├── quickstart.md # Phase 1 output (migration guide) +└── contracts/ # Phase 1 output (workflow contracts) + └── workflow-api.yml # Workflow inputs/outputs contract +``` + +### Source Code (repository root) + +```plaintext +.github/workflows/ +├── workflow.yml # MODIFIED: Unified CI + Release workflow +├── CI.yml # DEPRECATED: To be removed in future version +├── Get-Settings.yml # UNCHANGED: Settings loader +├── Build-Module.yml # UNCHANGED: Module builder +├── Build-Docs.yml # UNCHANGED: Documentation builder +├── Build-Site.yml # UNCHANGED: Site builder +├── Test-SourceCode.yml # UNCHANGED: Source code tests +├── Lint-SourceCode.yml # UNCHANGED: Source code linting +├── Test-Module.yml # UNCHANGED: Module tests +├── Test-ModuleLocal.yml # UNCHANGED: Local Pester tests +├── Get-TestResults.yml # UNCHANGED: Test aggregation +├── Get-CodeCoverage.yml # UNCHANGED: Coverage analysis +├── Publish-Module.yml # REMOVED: Logic moved to workflow.yml +├── Publish-Site.yml # REMOVED: Logic moved to workflow.yml +├── Workflow-Test-Default.yml # MODIFIED: Test unified workflow +├── Workflow-Test-Default-CI.yml # DEPRECATED: No longer needed +├── Workflow-Test-WithManifest.yml # MODIFIED: Test unified workflow +└── Workflow-Test-WithManifest-CI.yml # DEPRECATED: No longer needed + +docs/ +└── migration/ + └── v5-unified-workflow.md # NEW: Migration guide for consuming repos + +README.md # MODIFIED: Update workflow documentation +``` + +**Structure Decision**: Single project structure. This is a workflow consolidation within the Process-PSModule framework. The unified workflow.yml will incorporate conditional logic to determine whether to execute release operations based on trigger context (PR event vs main branch push). + +**Key Changes**: +1. **workflow.yml**: Enhanced with conditional Publish-Module and Publish-Site jobs +2. **CI.yml**: Marked as deprecated; will be removed in future release after migration period +3. **Publish-Module.yml** and **Publish-Site.yml**: Removed as separate files; logic inlined to workflow.yml +4. **Test workflows**: Updated to test unified workflow behavior +5. **Migration guide**: Comprehensive guide for consuming repositories to update their workflow references + +## Phase 0: Outline & Research + +### Research Questions + +Based on the specification NEEDS CLARIFICATION markers and technical analysis: + +1. **Publishing Target**: PowerShell Gallery (confirmed from existing workflow.yml) +2. **Versioning Strategy**: Semantic Versioning with PR labels (confirmed from Publish-PSModule@v2 usage) +3. **Manual Trigger Behavior**: Tests only (no releases) - inferred from existing workflow patterns +4. **Authentication**: PowerShell Gallery API key via secrets.APIKEY (confirmed) +5. **CI Time Limits**: No hard limits specified; existing workflow timeout defaults apply +6. **Conditional Execution Strategy**: Analyze existing workflow.yml and CI.yml differences + +### Analysis: Current Workflow Differences + +**CI.yml (Test-Only Mode)**: +- Triggers: `pull_request`, `workflow_dispatch`, `schedule` +- Permissions: `contents: read`, `pull-requests: write`, `statuses: write` (read-only, no releases) +- Jobs: Get-Settings → Build → Test → Results → Coverage +- **Missing**: Publish-Module, Publish-Site jobs + +**workflow.yml (CI + Release Mode)**: +- Triggers: `workflow_call` (called by consuming repos) +- Permissions: `contents: write`, `pull-requests: write`, `statuses: write`, `pages: write`, `id-token: write` +- Jobs: Get-Settings → Build → Test → Results → Coverage → **Publish-Module** → **Publish-Site** +- **Publish-Module condition**: `github.event_name == 'pull_request'` +- **Publish-Site condition**: `github.event_name == 'pull_request' && github.event.pull_request.merged == true` + +### Key Findings + +**Decision**: Merge workflows by adding intelligent conditionals to workflow.yml + +**Rationale**: +1. **CI.yml is already test-only**: It lacks publish jobs entirely +2. **workflow.yml has conditional publishing**: Publish jobs already check event context +3. **Minimal disruption**: Consuming repos already call workflow.yml; they won't need immediate changes +4. **Graceful deprecation**: CI.yml can be marked deprecated and removed later +5. **Trigger compatibility**: workflow.yml uses `workflow_call`, making it trigger-agnostic + +**Alternatives Considered**: +1. ❌ **Create new workflow, deprecate both**: High migration burden; all repos must update simultaneously +2. ❌ **Merge into CI.yml**: Consuming repos call workflow.yml, not CI.yml; would break all repos +3. ✅ **Enhance workflow.yml conditionals**: Minimal breaking changes; clear migration path + +### Conditional Execution Strategy + +The unified workflow will use these conditions for publish jobs: + +**Publish-Module**: +```yaml +if: | + needs.Get-Settings.result == 'success' && + needs.Get-TestResults.result == 'success' && + needs.Get-CodeCoverage.result == 'success' && + !cancelled() && + ( + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || + (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) + ) +``` + +**Publish-Site**: +```yaml +if: | + needs.Get-Settings.result == 'success' && + needs.Get-TestResults.result == 'success' && + needs.Get-CodeCoverage.result == 'success' && + needs.Build-Site.result == 'success' && + !cancelled() && + ( + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || + (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) + ) +``` + +**Rationale**: +- Publish only on merged PRs OR direct pushes to default branch +- Maintains existing behavior for current consumers +- Prevents accidental releases from unmerged PRs or non-default branches +- Compatible with manual triggers (workflow_dispatch) - tests run, releases skip + +**Output**: Research complete - no unknowns remain + +## Phase 1: Design & Contracts + +*Prerequisites: research.md complete ✓* + +### Design Entities + +From the specification and research, the following entities are required: + +1. **Workflow Execution Context**: Determines CI-only vs CI+Release mode +2. **Job Conditional Logic**: Implements intelligent skipping of publish jobs +3. **Trigger Event Classification**: Maps trigger types to execution modes +4. **Migration Path**: Defines consuming repository migration approach + +### Workflow State Model (data-model.md) + +The unified workflow operates in one of two modes based on trigger context: + +**Mode 1: CI-Only** (Tests without Release) +- Trigger Events: Unmerged PRs, manual triggers, scheduled runs, non-default branch pushes +- Executed Jobs: Get-Settings → Build → Test → Results/Coverage +- Skipped Jobs: Publish-Module, Publish-Site +- Permissions: Can use read-only or write (write preferred for consistency) + +**Mode 2: CI + Release** (Tests with Release) +- Trigger Events: Merged PRs to default branch, direct pushes to default branch +- Executed Jobs: Get-Settings → Build → Test → Results/Coverage → **Publish-Module → Publish-Site** +- Skipped Jobs: None (all jobs execute) +- Permissions: Requires write permissions (contents, pages, id-token) + +### Workflow API Contract (contracts/workflow-api.yml) + +The unified workflow maintains the same API surface as current workflow.yml: + +**Inputs**: (Unchanged) +- Name, SettingsPath, Debug, Verbose, Version, Prerelease, WorkingDirectory + +**Secrets**: (Unchanged) +- APIKey, TEST_APP_ENT_CLIENT_ID, TEST_APP_ENT_PRIVATE_KEY, etc. + +**Outputs**: (Unchanged) +- None (workflow uses job artifacts and GitHub release artifacts) + +**Breaking Changes**: +- CI.yml will be marked deprecated +- Consuming repositories using CI.yml should migrate to workflow.yml +- No immediate breaking changes for repositories already using workflow.yml + +### Test Scenarios (quickstart.md) + +The quickstart will serve as a migration guide with these scenarios: + +1. **Scenario: PR Opened on Feature Branch** + - Expected: CI tests run; no release operations + - Validation: Check job skips in workflow log + +2. **Scenario: PR Merged to Main Branch** + - Expected: CI tests run; release operations execute + - Validation: Check PowerShell Gallery and GitHub releases + +3. **Scenario: Direct Push to Main Branch** + - Expected: CI tests run; release operations execute + - Validation: Same as merged PR + +4. **Scenario: Manual Workflow Trigger** + - Expected: CI tests run; release operations skipped + - Validation: Check job skips in workflow log + +5. **Scenario: Repository Migration** + - Expected: Update workflow references from CI.yml to workflow.yml + - Validation: Verify PR and release workflows function correctly + +### Agent Context Update + +After design is complete, update `.github/copilot-instructions.md`: + +```markdown +## Recent Changes + +- 001-merge-ci-release-workflows: Unified workflow.yml handles CI and release with conditional execution (v5.0.0) +``` + +**Output**: data-model.md, contracts/workflow-api.yml, quickstart.md, updated .github/copilot-instructions.md +## Phase 2: Task Planning Approach + +*This section describes what the /tasks command will do - DO NOT execute during /plan* + +**Task Generation Strategy**: + +The /tasks command will generate implementation tasks organized into these categories: + +1. **Workflow Modification Tasks**: + - Update workflow.yml conditional logic for Publish-Module + - Update workflow.yml conditional logic for Publish-Site + - Add deprecation warning to CI.yml header + - Update workflow permissions documentation + +2. **Test Infrastructure Tasks**: + - Create test scenarios for CI-only mode validation + - Create test scenarios for CI + Release mode validation + - Update CI validation workflow to test unified workflow + - Create manual testing procedures document + +3. **Documentation Tasks**: + - Create migration guide (docs/migration/v5-unified-workflow.md) + - Update README.md with unified workflow documentation + - Update workflow.yml inline documentation + - Add deprecation notice to CI.yml + +4. **Validation Tasks**: + - Test PR opened scenario (CI-only mode) + - Test PR merged scenario (CI + Release mode) + - Test direct push to main scenario (CI + Release mode) + - Test manual trigger scenario (CI-only mode) + - Test scheduled run scenario (CI-only mode) + +**Ordering Strategy**: + +1. **Phase A: Documentation First** (TDD approach - define expected behavior) + - Write migration guide + - Update README documentation + - Document test scenarios + +2. **Phase B: Test Infrastructure** (Tests before implementation) + - Create test validation workflows + - Define manual testing procedures + - Create test result validation criteria + +3. **Phase C: Implementation** (Make tests pass) + - Update workflow.yml conditionals + - Deprecate CI.yml + - Update workflow documentation + +4. **Phase D: Validation** (Verify implementation) + - Execute test scenarios + - Validate migration guide accuracy + - Test against real repository + +**Parallel Execution Markers**: Tasks marked [P] can be executed in parallel + +**Estimated Output**: 15-20 numbered, ordered tasks in tasks.md + +**IMPORTANT**: This phase is executed by the /tasks command, NOT by /plan + +## Phase 3+: Future Implementation + +*These phases are beyond the scope of the /plan command* + +**Phase 3**: Task execution (/tasks command creates tasks.md) +**Phase 4**: Implementation (execute tasks.md following constitutional principles) +**Phase 5**: Validation (run tests, execute quickstart.md, performance validation) + +## Complexity Tracking + +*Fill ONLY if Constitution Check has violations that must be justified* + +No constitutional violations identified. All constitutional principles are satisfied: + +- ✅ Workflow-First Design: Implemented as reusable workflow modification +- ✅ Test-Driven Development: Test scenarios documented before implementation +- ✅ Platform Independence: No platform-specific changes required +- ✅ Quality Gates: Existing quality gates preserved +- ✅ Continuous Delivery: SemVer bump to v5.0.0 (Major breaking change) + +## Progress Tracking + +*This checklist is updated during execution flow* + +**Phase Status**: + +- [x] Phase 0: Research complete (/plan command) +- [x] Phase 1: Design complete (/plan command) +- [x] Phase 2: Task planning complete (/plan command - describe approach only) +- [ ] Phase 3: Tasks generated (/tasks command) +- [ ] Phase 4: Implementation complete +- [ ] Phase 5: Validation passed + +**Gate Status**: + +- [x] Initial Constitution Check: PASS +- [x] Post-Design Constitution Check: PASS +- [x] All NEEDS CLARIFICATION resolved (via research phase) +- [x] Complexity deviations documented (none identified) + +**Artifacts Generated**: + +- [x] research.md (Phase 0) +- [x] data-model.md (Phase 1) +- [x] contracts/workflow-api.md (Phase 1) +- [x] quickstart.md (Phase 1 - serves as migration guide) +- [x] .github/copilot-instructions.md (updated) + +--- +*Based on Constitution - See `.specify/memory/constitution.md`* diff --git a/specs/001-merge-ci-release-workflows/quickstart.md b/specs/001-merge-ci-release-workflows/quickstart.md new file mode 100644 index 00000000..9ac6ad78 --- /dev/null +++ b/specs/001-merge-ci-release-workflows/quickstart.md @@ -0,0 +1,410 @@ +# Quickstart: Migrating to Unified CI and Release Workflow + +**Feature**: 001-merge-ci-release-workflows +**Date**: 2025-10-02 +**Target Audience**: PowerShell module maintainers consuming Process-PSModule workflows + +## Overview + +Process-PSModule v5.0.0 introduces a **unified workflow** that handles both continuous integration testing and automated release publishing in a single workflow file. This eliminates the need to maintain separate CI.yml and workflow.yml files. + +**Key Benefits**: +- ✅ Single source of truth for CI/CD pipeline +- ✅ Reduced configuration complexity +- ✅ Consistent behavior across all trigger scenarios +- ✅ Easier maintenance across multiple repositories + +## Migration Scenarios + +### Scenario 1: Already Using workflow.yml Only + +**Current State**: Your repository calls workflow.yml for all events (PRs and merges) + +**Impact**: ✅ **None** - Your repository continues working without changes + +**Action Required**: None (optional: review this guide for new features) + +**Example Current Workflow**: +```yaml +name: Process-PSModule + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + Process-PSModule: + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v4 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +**After v5 Upgrade**: Update version tag to `@v5` +```yaml +jobs: + Process-PSModule: + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v5 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +### Scenario 2: Using Both CI.yml and workflow.yml + +**Current State**: Your repository has two workflow files: +- One calling CI.yml for PR validation +- One calling workflow.yml for releases + +**Impact**: ⚠️ **Migration Recommended** - CI.yml is deprecated + +**Action Required**: Consolidate to single workflow file calling workflow.yml + +**Example Current Setup**: + +File: `.github/workflows/CI.yml` (PR validation) +```yaml +name: CI + +on: + pull_request: + branches: [main] + +jobs: + CI: + uses: PSModule/Process-PSModule/.github/workflows/CI.yml@v4 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +File: `.github/workflows/Process-PSModule.yml` (Release) +```yaml +name: Process-PSModule + +on: + pull_request: + branches: [main] + types: [closed] + +jobs: + Process-PSModule: + if: github.event.pull_request.merged == true + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v4 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +**After Migration** (single unified workflow): + +File: `.github/workflows/Process-PSModule.yml` +```yaml +name: Process-PSModule + +on: + pull_request: + branches: [main] + types: [opened, reopened, synchronize, closed, labeled] + push: + branches: [main] + workflow_dispatch: + +jobs: + Process-PSModule: + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v5 + secrets: + APIKEY: ${{ secrets.APIKEY }} + # Add any test-related secrets your module needs +``` + +**Cleanup**: Delete `.github/workflows/CI.yml` from your repository + +### Scenario 3: Custom Trigger Configurations + +**Current State**: Your repository has custom workflow triggers or conditions + +**Impact**: ⚠️ **Review Required** - Ensure trigger patterns align with unified workflow + +**Action Required**: Review and update triggers to match recommended patterns + +**Recommended Trigger Pattern**: +```yaml +on: + pull_request: + branches: [main] + types: + - opened # PR created + - reopened # PR reopened + - synchronize # New commits pushed + - closed # PR closed (merged or closed without merge) + - labeled # PR labeled (for prerelease publishing) + push: + branches: [main] # Direct pushes to main + workflow_dispatch: # Manual triggers + schedule: # Nightly regression tests (optional) + - cron: '0 2 * * *' # 2 AM daily +``` + +**Key Points**: +- `closed` type required to detect merged PRs +- `labeled` type enables prerelease publishing workflow +- `workflow_dispatch` allows manual testing without releases +- `schedule` useful for nightly validation (optional) + +## Validation Steps + +After migration, validate these scenarios: + +### Test 1: PR Opened (CI-Only Mode) + +**Steps**: +1. Create a feature branch +2. Make a code change +3. Open a pull request to main + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute (build, test, lint) +- ✅ Test results reported as PR status checks +- ❌ Publish-Module job skipped +- ❌ Publish-Site job skipped + +**Validation**: +```bash +# Check workflow run in GitHub Actions UI +# Verify Publish-Module and Publish-Site show as "Skipped" +``` + +### Test 2: PR Updated (CI-Only Mode) + +**Steps**: +1. Push new commits to the open PR + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute with new changes +- ❌ Publish jobs still skipped + +### Test 3: PR Merged (CI + Release Mode) + +**Steps**: +1. Merge the pull request to main branch + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute +- ✅ Publish-Module job executes (if tests pass) +- ✅ Publish-Site job executes (if tests pass) +- ✅ Module published to PowerShell Gallery +- ✅ Documentation deployed to GitHub Pages +- ✅ GitHub release created + +**Validation**: +```bash +# Check PowerShell Gallery for new version +Find-PSResource -Name YourModuleName | Select-Object -First 1 + +# Check GitHub Releases +# Visit: https://github.com/yourorg/yourrepo/releases + +# Check GitHub Pages +# Visit: https://yourorg.github.io/yourrepo/ +``` + +### Test 4: Manual Trigger (CI-Only Mode) + +**Steps**: +1. Go to Actions tab in GitHub +2. Select "Process-PSModule" workflow +3. Click "Run workflow" button +4. Select branch and click "Run workflow" + +**Expected Behavior**: +- ✅ Workflow runs on selected branch +- ✅ All CI jobs execute +- ❌ Publish jobs skipped (no release from manual trigger) + +### Test 5: Direct Push to Main (CI + Release Mode) + +**Steps**: +1. Push commits directly to main branch (bypass PR) + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute +- ✅ Publish jobs execute (if tests pass) + +**Warning**: Direct pushes skip PR review; use with caution + +## Troubleshooting + +### Issue: Workflow Not Triggering on PR + +**Symptom**: Workflow doesn't run when PR opened + +**Solution**: Ensure your workflow file includes the correct PR trigger types +```yaml +on: + pull_request: + branches: [main] + types: [opened, reopened, synchronize, closed, labeled] +``` + +### Issue: Publish Jobs Not Running After Merge + +**Symptom**: PR merged but publish jobs skipped + +**Possible Causes**: +1. Tests failed - check test results +2. PR not actually merged (closed without merge) +3. Workflow file missing `closed` trigger type + +**Solution**: Check workflow run logs for skip reason; verify PR actually merged + +### Issue: Accidental Release from Unmerged PR + +**Symptom**: Module published before PR merged + +**Cause**: Likely using prerelease workflow with `prerelease` label + +**Solution**: This is expected behavior for prerelease publishing. Remove `prerelease` label if unintended. + +### Issue: Workflow Runs But Skips All Jobs + +**Symptom**: Workflow triggers but all jobs show as skipped + +**Possible Causes**: +1. Settings file has skip flags enabled +2. Workflow conditions not met + +**Solution**: Check `.github/PSModule.yml` for skip settings: +```yaml +Build: + Module: + Skip: false # Ensure not set to true +Test: + Skip: false +``` + +## Configuration Options + +The unified workflow respects all existing settings in `.github/PSModule.yml`: + +### Skip Publishing + +Prevent releases even on merged PRs: +```yaml +Publish: + Module: + Skip: true # Skip PowerShell Gallery publishing + Site: + Skip: true # Skip GitHub Pages deployment +``` + +### Versioning Configuration + +```yaml +Publish: + Module: + AutoPatching: true # Auto-apply patch version on unlabeled PRs + IncrementalPrerelease: true # Use incremental prerelease tags + MajorLabels: ['major', 'breaking'] + MinorLabels: ['minor', 'feature'] + PatchLabels: ['patch', 'fix', 'bug'] +``` + +### Test Configuration + +```yaml +Test: + CodeCoverage: + Skip: false + PercentTarget: 80 # Minimum code coverage percentage + TestResults: + Skip: false +``` + +## Best Practices + +### 1. Use PR Workflow for All Changes + +**Recommended**: Always use pull requests for code changes +``` +feature branch → PR → merge to main → automatic release +``` + +**Avoid**: Direct pushes to main (bypasses review) + +### 2. Label PRs for Version Control + +**Major Release** (breaking changes): +```bash +gh pr edit --add-label "major" +``` + +**Minor Release** (new features): +```bash +gh pr edit --add-label "minor" +``` + +**Patch Release** (bug fixes): +```bash +gh pr edit --add-label "patch" +# OR enable AutoPatching for automatic patch bumps +``` + +### 3. Enable Nightly Validation (Optional) + +Add scheduled trigger for regression testing: +```yaml +on: + schedule: + - cron: '0 2 * * *' # 2 AM daily +``` + +### 4. Use Manual Triggers for Testing + +Test workflow changes without publishing: +1. Push changes to feature branch +2. Manually trigger workflow on that branch +3. Verify workflow behaves correctly +4. Merge PR when validated + +## Migration Checklist + +Use this checklist when migrating a repository: + +- [ ] Backup existing workflow files +- [ ] Update workflow to use workflow.yml@v5 +- [ ] Add required PR trigger types (opened, reopened, synchronize, closed, labeled) +- [ ] Remove or deprecate CI.yml references +- [ ] Update repository documentation referencing workflow files +- [ ] Test PR opened scenario (CI-only) +- [ ] Test PR merged scenario (CI + release) +- [ ] Test manual trigger scenario (CI-only) +- [ ] Verify PowerShell Gallery publishing works +- [ ] Verify GitHub Pages deployment works +- [ ] Delete deprecated workflow files (after validation) + +## Support + +For issues or questions about migration: + +1. Check the [Process-PSModule documentation](https://github.com/PSModule/Process-PSModule) +2. Review workflow run logs in GitHub Actions +3. Open an issue on the Process-PSModule repository +4. Consult the [workflow API contract](./contracts/workflow-api.md) + +## Next Steps + +After successful migration: + +1. ✅ Monitor first few releases to ensure smooth operation +2. ✅ Update team documentation about the unified workflow +3. ✅ Share migration experience with other repository maintainers +4. ✅ Consider migrating other repositories following the same pattern + +--- + +**Last Updated**: 2025-10-02 +**Process-PSModule Version**: v5.0.0 +**Breaking Change**: Yes - CI.yml deprecated diff --git a/specs/001-merge-ci-release-workflows/research.md b/specs/001-merge-ci-release-workflows/research.md new file mode 100644 index 00000000..26bed910 --- /dev/null +++ b/specs/001-merge-ci-release-workflows/research.md @@ -0,0 +1,286 @@ +# Research: Unified CI and Release Workflow + +**Feature**: 001-merge-ci-release-workflows +**Date**: 2025-10-02 +**Status**: Complete + +## Research Questions Resolved + +### 1. Publishing Target + +**Decision**: PowerShell Gallery + +**Rationale**: +- Existing workflow.yml uses `PSModule/Publish-PSModule@v2` action +- Action publishes to PowerShell Gallery via `APIKey` secret +- All PSModule repositories publish to PowerShell Gallery +- No private feed or alternative registry support currently exists + +**Alternatives Considered**: +- Private feeds (NuGet, Azure Artifacts): Not currently used by PSModule repositories +- Multiple registries: Would add complexity without current need + +### 2. Versioning Strategy + +**Decision**: Semantic Versioning with PR labels + +**Rationale**: +- Existing Publish-PSModule action uses PR labels for version bumping +- Labels: `major`, `minor`, `patch` (or configured alternatives) +- SemVer 2.0.0 compliant version increments +- Prerelease support via `prerelease` label +- AutoPatching option for automatic patch bumps + +**Alternatives Considered**: +- Date-based versioning: Available via DatePrereleaseFormat but not default +- Manual version tags: Less automated, more error-prone + +### 3. Manual Trigger Behavior + +**Decision**: Tests only (no releases) + +**Rationale**: +- Manual triggers (`workflow_dispatch`) should not automatically publish +- Releases should only occur from PR merges or direct pushes to main +- Prevents accidental releases from manual workflow runs +- Consistent with CI-only behavior for non-release triggers + +**Alternatives Considered**: +- Allow releases on manual trigger: Risky; could lead to unintended publishes +- Add manual trigger input for release control: Adds complexity without clear benefit + +### 4. Authentication + +**Decision**: PowerShell Gallery API key via `secrets.APIKEY` + +**Rationale**: +- Existing workflow requires `APIKey` secret +- PowerShell Gallery publishing requires API key authentication +- GitHub token (`GITHUB_TOKEN`) used for GitHub Releases +- No additional authentication mechanisms needed + +**Alternatives Considered**: +- Service principal / Azure AD: Not applicable for PowerShell Gallery +- Multiple API keys: Not needed; single gallery per repository + +### 5. CI Time Limits + +**Decision**: Use GitHub Actions default timeouts (6 hours per job, 72 hours per workflow) + +**Rationale**: +- No hard time limits specified in existing workflows +- Current workflows complete in 5-15 minutes typically +- GitHub Actions default timeouts are sufficient +- Individual jobs can be configured with custom timeouts if needed + +**Alternatives Considered**: +- Enforce specific time limits: Not necessary; existing workflows perform adequately +- Progressive timeout warnings: Adds complexity without clear benefit + +## Workflow Consolidation Analysis + +### Current Workflow Architecture + +**CI.yml** (Test-Only Mode): +```yaml +Triggers: pull_request, workflow_dispatch, schedule +Permissions: contents: read, pull-requests: write, statuses: write +Jobs: + - Get-Settings + - Build-Module + - Build-Docs + - Build-Site + - Test-SourceCode + - Lint-SourceCode + - Test-Module + - BeforeAll-ModuleLocal + - Test-ModuleLocal + - AfterAll-ModuleLocal + - Get-TestResults + - Get-CodeCoverage +Missing: Publish-Module, Publish-Site +``` + +**workflow.yml** (CI + Release Mode): +```yaml +Triggers: workflow_call (called by consuming repositories) +Permissions: contents: write, pull-requests: write, statuses: write, pages: write, id-token: write +Jobs: + - Get-Settings + - Build-Module + - Build-Docs + - Build-Site + - Test-SourceCode + - Lint-SourceCode + - Test-Module + - BeforeAll-ModuleLocal + - Test-ModuleLocal + - AfterAll-ModuleLocal + - Get-TestResults + - Get-CodeCoverage + - Publish-Site (conditional on merged PR) + - Publish-Module (conditional on PR event) +``` + +### Key Differences Identified + +1. **Triggers**: CI.yml has explicit triggers; workflow.yml uses `workflow_call` +2. **Permissions**: workflow.yml has write permissions for releases; CI.yml is read-only +3. **Publish Jobs**: Only workflow.yml includes Publish-Module and Publish-Site +4. **Conditionals**: workflow.yml already has conditional publishing logic + +### Consolidation Strategy + +**Decision**: Enhance workflow.yml conditional logic; deprecate CI.yml + +**Rationale**: +1. **Minimal Breaking Changes**: Consuming repositories already call workflow.yml +2. **Clear Migration Path**: CI.yml can remain for backward compatibility during migration +3. **Existing Conditionals**: workflow.yml already has publish conditionals; just need refinement +4. **Permission Safety**: Unified workflow maintains appropriate permissions for both modes + +**Implementation Approach**: + +1. **Update Publish-Module condition**: + - Current: `github.event_name == 'pull_request'` + - New: `(github.event_name == 'pull_request' && github.event.pull_request.merged == true) || (github.event_name == 'push' && github.ref == default_branch)` + +2. **Update Publish-Site condition**: + - Current: `github.event_name == 'pull_request' && github.event.pull_request.merged == true` + - New: Same as Publish-Module (add push trigger support) + +3. **Maintain existing job dependencies**: No changes to job execution order + +4. **Preserve permissions**: Unified workflow maintains write permissions + +### Conditional Execution Logic + +**Publish-Module Condition**: +```yaml +if: | + needs.Get-Settings.result == 'success' && + needs.Get-TestResults.result == 'success' && + needs.Get-CodeCoverage.result == 'success' && + !cancelled() && + ( + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || + (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) + ) +``` + +**Rationale**: +- Tests must pass (Get-TestResults, Get-CodeCoverage success) +- Workflow must not be cancelled +- Publish only on: + - Merged pull requests to default branch, OR + - Direct pushes to default branch +- Skips on: + - Unmerged pull requests + - Manual triggers (workflow_dispatch) + - Scheduled runs + - Pushes to non-default branches + +**Publish-Site Condition**: +```yaml +if: | + needs.Get-Settings.result == 'success' && + needs.Get-TestResults.result == 'success' && + needs.Get-CodeCoverage.result == 'success' && + needs.Build-Site.result == 'success' && + !cancelled() && + ( + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || + (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) + ) +``` + +**Rationale**: Same as Publish-Module, plus requires successful Build-Site job + +## Alternatives Considered + +### Alternative 1: Create New Workflow, Deprecate Both + +**Approach**: Create workflow-v5.yml, mark both CI.yml and workflow.yml deprecated + +**Pros**: +- Clean slate; no technical debt +- Clear versioning signal (v5) + +**Cons**: +- High migration burden; all consuming repositories must update simultaneously +- Increased risk of breakage across multiple repositories +- Longer migration timeline +- Two deprecated workflows to maintain during transition + +**Verdict**: ❌ Rejected due to high migration risk and coordination burden + +### Alternative 2: Merge into CI.yml + +**Approach**: Enhance CI.yml with release logic; deprecate workflow.yml + +**Pros**: +- CI.yml already has explicit triggers +- Clear naming for "CI + Release" + +**Cons**: +- All consuming repositories call workflow.yml, not CI.yml +- Would break every consuming repository immediately +- Requires simultaneous updates across all repositories +- Violates least-surprise principle (existing references break) + +**Verdict**: ❌ Rejected due to immediate breakage of all consuming repositories + +### Alternative 3: Enhance workflow.yml (SELECTED) + +**Approach**: Add refined conditionals to workflow.yml; mark CI.yml deprecated + +**Pros**: +- Minimal breaking changes; consuming repos continue working +- Graceful migration path with backward compatibility period +- workflow.yml already has conditional logic foundation +- Clear deprecation path for CI.yml + +**Cons**: +- CI.yml remains in codebase during migration (minor maintenance burden) +- Slightly less obvious from naming that workflow.yml handles both CI and release + +**Verdict**: ✅ Selected - balances functionality with migration safety + +## Migration Considerations + +### Consuming Repository Impact + +**Immediate Changes Required**: None (if using workflow.yml already) + +**Recommended Changes**: +1. Update documentation referencing CI.yml +2. Remove any direct CI.yml references (if present) +3. Consolidate workflow triggers in repository workflows +4. Review and update workflow permissions if needed + +### Migration Timeline + +**Phase 1** (v5.0.0 release): +- Unified workflow.yml released +- CI.yml marked deprecated with warning comment +- Migration guide published + +**Phase 2** (v5.x maintenance period - 6+ months): +- Support both workflow patterns +- Respond to migration issues +- Update consuming repositories incrementally + +**Phase 3** (v6.0.0 release): +- Remove CI.yml entirely +- Complete documentation cleanup +- Final migration verification + +## Conclusion + +All research questions resolved. The unified workflow consolidation strategy is clear: +- Enhance workflow.yml with refined conditional logic +- Deprecate CI.yml with graceful migration period +- Maintain backward compatibility during transition +- Provide comprehensive migration guide for consuming repositories + +**Ready for Phase 1: Design & Contracts** From aed14b63d2ac4245f1982d916efd024ee261bbbe Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 13:39:29 +0200 Subject: [PATCH 3/6] docs: Integrate clarifications into specification - Added Clarifications session 2025-10-02 with 5 resolved questions - Updated FR-008: Publishing target is PowerShell Gallery - Updated FR-009: Semantic versioning with PR labels - Updated FR-011: Manual triggers execute tests only - Updated FR-012: Authentication via APIKEY and GITHUB_TOKEN - Updated NFR-001: GitHub Actions default timeouts - Marked requirement completeness checklist complete - All [NEEDS CLARIFICATION] markers removed --- specs/001-merge-ci-release-workflows/spec.md | 22 ++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/specs/001-merge-ci-release-workflows/spec.md b/specs/001-merge-ci-release-workflows/spec.md index 606898e4..b4d0e461 100644 --- a/specs/001-merge-ci-release-workflows/spec.md +++ b/specs/001-merge-ci-release-workflows/spec.md @@ -36,17 +36,17 @@ As a PowerShell module maintainer managing multiple repositories, I need a singl | **FR-005** | Workflow MUST skip release operations when running on pull request events | | **FR-006** | Workflow MUST report test results as PR status checks | | **FR-007** | Workflow MUST fail fast and halt execution if CI tests fail | -| **FR-008** | Workflow MUST publish module releases to [NEEDS CLARIFICATION: target registry not specified - PowerShell Gallery, private feed, both?] | -| **FR-009** | Workflow MUST create GitHub releases with [NEEDS CLARIFICATION: versioning strategy not specified - semantic versioning, date-based, manual tags?] | +| **FR-008** | Workflow MUST publish module releases to PowerShell Gallery | +| **FR-009** | Workflow MUST create GitHub releases with semantic versioning based on PR labels (major, minor, patch) | | **FR-010** | Workflow MUST be compatible with existing repository structures used in PSModule repositories | -| **FR-011** | Workflow MUST support manual triggering (workflow_dispatch) with [NEEDS CLARIFICATION: should manual triggers allow release operations, or tests only?] | -| **FR-012** | Workflow MUST handle authentication for [NEEDS CLARIFICATION: authentication targets not specified - PowerShell Gallery API keys, GitHub tokens, other credentials?] | +| **FR-011** | Workflow MUST support manual triggering (workflow_dispatch) with tests-only execution (no release operations) | +| **FR-012** | Workflow MUST handle authentication for PowerShell Gallery publishing via secrets.APIKEY and GitHub Releases via GITHUB_TOKEN | ### Non-Functional Requirements | ID | Requirement | |----|-------------| -| **NFR-001** | Workflow MUST complete CI test phase within reasonable time limits [NEEDS CLARIFICATION: acceptable time limits not specified] | +| **NFR-001** | Workflow MUST complete CI test phase using GitHub Actions default timeouts (6 hours per job, 72 hours per workflow; typical completion in 5-15 minutes) | | **NFR-002** | Workflow MUST be maintainable as a single source of truth across multiple repositories | | **NFR-003** | Workflow MUST provide clear logging to distinguish CI and release phases | | **NFR-004** | Workflow MUST be idempotent for release operations (safe to re-run without duplicate publishes) | @@ -81,6 +81,16 @@ As a PowerShell module maintainer managing multiple repositories, I need a singl | **Trigger Context** | Runtime information determining whether workflow runs in PR mode or release mode | | **Test Results** | Output from CI phase determining whether release phase can proceed | +## Clarifications + +### Session 2025-10-02 + +- Q: What is the target registry for module publishing? → A: PowerShell Gallery +- Q: What versioning strategy should be used for releases? → A: Semantic versioning with PR labels (major, minor, patch) +- Q: Should manual triggers allow release operations? → A: No, tests only +- Q: What authentication targets are required? → A: PowerShell Gallery API key via secrets.APIKEY +- Q: What are acceptable CI time limits? → A: GitHub Actions default timeouts (6 hours per job, 72 hours per workflow) + --- **Feature Branch**: `001-merge-ci-release-workflows` @@ -101,7 +111,7 @@ As a PowerShell module maintainer managing multiple repositories, I need a singl ### Requirement Completeness -- [ ] No [NEEDS CLARIFICATION] markers remain +- [x] No [NEEDS CLARIFICATION] markers remain - [x] Requirements are testable and unambiguous - [x] Success criteria are measurable - [x] Scope is clearly bounded From 764ac947efd74229951259a104dd2cd1a1a4ad13 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 13:43:59 +0200 Subject: [PATCH 4/6] feat: Generate implementation tasks for unified workflow - Created 28 tasks across 5 phases (Setup, Tests, Core, Integration, Polish) - Phase 3.2: 6 test tasks covering CI-only, CI+Release, and manual trigger modes - Phase 3.3: 6 core tasks for conditional execution logic in workflow.yml - Phase 3.4: 6 integration tasks for deprecation and file removal - Phase 3.5: 7 polish tasks for documentation and validation - Marked 15 tasks as parallel [P] (different files, no dependencies) - Sequential tasks for workflow.yml modifications (T010-T015) - All test tasks before implementation (TDD red-green-refactor) - Added validation checklist (all items passed) - Updated PR #199 description with task checkboxes --- specs/001-merge-ci-release-workflows/tasks.md | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 specs/001-merge-ci-release-workflows/tasks.md diff --git a/specs/001-merge-ci-release-workflows/tasks.md b/specs/001-merge-ci-release-workflows/tasks.md new file mode 100644 index 00000000..a622d7b6 --- /dev/null +++ b/specs/001-merge-ci-release-workflows/tasks.md @@ -0,0 +1,194 @@ +# Tasks: Unified CI and Release Workflow + +**Input**: Design documents from `/specs/001-merge-ci-release-workflows/` +**Prerequisites**: plan.md (required), research.md, data-model.md, contracts/ + +## Execution Flow (main) + +1. Load plan.md from feature directory + → Extract: GitHub Actions YAML, PowerShell 7.4+, reusable workflow structure +2. Load optional design documents: + → data-model.md: Extract TriggerContext, JobExecutionPlan entities + → contracts/workflow-api.md: Extract workflow inputs, secrets, conditional logic + → research.md: Extract decisions on conditional execution, authentication + → quickstart.md: Extract migration scenarios +3. Generate tasks by category: + → Setup: Repository structure validation, deprecation notices + → Tests: Workflow validation tests for CI-only and CI+Release modes + → Core: Conditional job execution logic in workflow.yml + → Integration: Deprecation of CI.yml, removal of separate publish workflows + → Polish: Documentation updates, migration guide validation +4. Apply task rules: + → Different workflow files = mark [P] for parallel + → Same workflow file = sequential (no [P]) + → Tests before implementation (TDD) +5. Number tasks sequentially (T001, T002...) +6. Generate dependency graph +7. Create parallel execution examples +8. Validate task completeness: + → Workflow API contract validated? + → Both execution modes tested? + → Migration paths documented? +9. Return: SUCCESS (tasks ready for execution) + +## Format: `[ID] [P?] Description` + +- **[P]**: Can run in parallel (different files, no dependencies) +- Include exact file paths in descriptions + +## Path Conventions + +This is a GitHub Actions workflow project at repository root: +- `.github/workflows/` - Workflow YAML files +- `docs/migration/` - Migration guides +- `README.md` - Project documentation + +## Phase 3.1: Setup + +- [ ] T001 Validate current workflow structure in .github/workflows/ +- [ ] T002 Create migration documentation directory docs/migration/ +- [ ] T003 Add deprecation notice to .github/workflows/CI.yml header + +## Phase 3.2: Tests First (TDD) ⚠️ MUST COMPLETE BEFORE 3.3 + +**CRITICAL: These tests MUST be written and MUST FAIL before ANY implementation** + +- [ ] T004 [P] Create test workflow for CI-only mode (unmerged PR) in .github/workflows/Test-Workflow-CI-Only.yml +- [ ] T005 [P] Create test workflow for CI+Release mode (merged PR) in .github/workflows/Test-Workflow-Release.yml +- [ ] T006 [P] Create test workflow for manual trigger behavior in .github/workflows/Test-Workflow-Manual.yml +- [ ] T007 [P] Update .github/workflows/Workflow-Test-Default.yml to test unified workflow +- [ ] T008 [P] Update .github/workflows/Workflow-Test-WithManifest.yml to test unified workflow +- [ ] T009 Create validation script to verify conditional job execution in tests/Validate-ConditionalExecution.Tests.ps1 + +## Phase 3.3: Core Implementation (ONLY after tests are failing) + +- [ ] T010 Add conditional execution logic to Publish-Module job in .github/workflows/workflow.yml +- [ ] T011 Add conditional execution logic to Publish-Site job in .github/workflows/workflow.yml +- [ ] T012 Update workflow triggers in .github/workflows/workflow.yml to handle all events +- [ ] T013 Update workflow permissions in .github/workflows/workflow.yml for both modes +- [ ] T014 Add workflow comments documenting CI-Only vs CI+Release execution paths in .github/workflows/workflow.yml +- [ ] T015 Verify all job dependencies correctly chain CI before Release jobs in .github/workflows/workflow.yml + +## Phase 3.4: Integration + +- [ ] T016 Add deprecation warning to .github/workflows/CI.yml with migration instructions +- [ ] T017 [P] Remove .github/workflows/Publish-Module.yml (logic now in workflow.yml) +- [ ] T018 [P] Remove .github/workflows/Publish-Site.yml (logic now in workflow.yml) +- [ ] T019 [P] Mark .github/workflows/Workflow-Test-Default-CI.yml as deprecated +- [ ] T020 [P] Mark .github/workflows/Workflow-Test-WithManifest-CI.yml as deprecated +- [ ] T021 Update workflow version references from v4 to v5 in test workflows + +## Phase 3.5: Polish + +- [ ] T022 [P] Create migration guide docs/migration/v5-unified-workflow.md with all three scenarios +- [ ] T023 [P] Update README.md with unified workflow documentation and breaking change notice +- [ ] T024 [P] Update .github/copilot-instructions.md with unified workflow as active technology +- [ ] T025 [P] Create manual test checklist docs/migration/manual-testing.md for consuming repositories +- [ ] T026 Run manual validation of all three migration scenarios from quickstart.md +- [ ] T027 Verify workflow execution time has no regression compared to separate workflows +- [ ] T028 [P] Add CHANGELOG.md entry for v5.0.0 breaking change + +## Dependencies + +### Phase Dependencies +- Setup (T001-T003) before all other phases +- Tests (T004-T009) before Core implementation (T010-T015) +- Core (T010-T015) before Integration (T016-T021) +- Integration (T016-T021) before Polish (T022-T028) + +### Specific Task Dependencies +- T004, T005, T006 must fail before T010, T011 implemented +- T007, T008 depend on T004, T005, T006 being written +- T010 blocks T016, T017, T018 (workflow.yml must have publish logic before removing separate files) +- T015 depends on T010, T011, T012, T013, T014 (all workflow changes complete) +- T021 depends on T010-T015 (v5 workflow ready) +- T022 depends on T016-T021 (migration scenarios finalized) +- T026 depends on T022 (migration guide complete) + +## Parallel Execution Examples + +### Phase 3.2: Tests (All Parallel) +```plaintext +# Launch all test creation tasks together: +Task: "Create test workflow for CI-only mode (unmerged PR) in .github/workflows/Test-Workflow-CI-Only.yml" +Task: "Create test workflow for CI+Release mode (merged PR) in .github/workflows/Test-Workflow-Release.yml" +Task: "Create test workflow for manual trigger behavior in .github/workflows/Test-Workflow-Manual.yml" +Task: "Update .github/workflows/Workflow-Test-Default.yml to test unified workflow" +Task: "Update .github/workflows/Workflow-Test-WithManifest.yml to test unified workflow" +``` + +### Phase 3.4: Integration (File Removals/Deprecations Parallel) +```plaintext +# Launch deprecation tasks together (different files): +Task: "Remove .github/workflows/Publish-Module.yml (logic now in workflow.yml)" +Task: "Remove .github/workflows/Publish-Site.yml (logic now in workflow.yml)" +Task: "Mark .github/workflows/Workflow-Test-Default-CI.yml as deprecated" +Task: "Mark .github/workflows/Workflow-Test-WithManifest-CI.yml as deprecated" +``` + +### Phase 3.5: Polish (Documentation Parallel) +```plaintext +# Launch documentation tasks together: +Task: "Create migration guide docs/migration/v5-unified-workflow.md with all three scenarios" +Task: "Update README.md with unified workflow documentation and breaking change notice" +Task: "Update .github/copilot-instructions.md with unified workflow as active technology" +Task: "Create manual test checklist docs/migration/manual-testing.md for consuming repositories" +Task: "Add CHANGELOG.md entry for v5.0.0 breaking change" +``` + +## Notes + +- **[P] tasks** = different files, no dependencies, safe to run in parallel +- **Sequential tasks** (no [P]) = modify same file (.github/workflows/workflow.yml) and must run in order +- Verify all test workflows FAIL before implementing conditional logic (TDD Red phase) +- Commit after each task to enable rollback if needed +- Test workflow execution locally where possible using `act` or GitHub CLI +- Avoid: modifying workflow.yml in multiple parallel tasks (sequential T010-T015) + +## Task Generation Rules + +*Applied during main() execution* + +1. **From Contracts** (workflow-api.md): + - Workflow API contract → test workflow validation tasks [P] + - Conditional execution logic → implementation tasks (sequential, same file) + - Input/output compatibility → validation test tasks [P] + +2. **From Data Model** (data-model.md): + - TriggerContext entity → conditional logic implementation tasks + - CI-Only execution mode → test workflow task + - CI+Release execution mode → test workflow task + - JobExecutionPlan → job dependency validation task + +3. **From Research** (research.md): + - Publishing target decision → Publish-Module job update task + - Versioning strategy → version reference update tasks + - Manual trigger behavior → manual trigger test task + - Authentication → secrets validation task + +4. **From Quickstart** (quickstart.md): + - Migration Scenario 1 → documentation task + - Migration Scenario 2 → documentation task + - Migration Scenario 3 → documentation task + - Manual testing steps → manual validation task + +5. **Ordering**: + - Setup → Tests → Core (workflow.yml mods) → Integration (file removals) → Polish (docs) + - All tests before implementation (strict TDD) + - Sequential tasks within workflow.yml (T010-T015) + - Parallel tasks for different files (tests, docs, deprecations) + +## Validation Checklist + +*GATE: Checked by main() before returning* + +- [x] All contracts have corresponding tests (workflow-api.md → T004-T008) +- [x] All entities have tasks (TriggerContext → T010, JobExecutionPlan → T015) +- [x] All tests come before implementation (T004-T009 before T010-T015) +- [x] Parallel tasks truly independent (different files: [P] marked correctly) +- [x] Each task specifies exact file path (all tasks include file paths) +- [x] No task modifies same file as another [P] task (workflow.yml tasks sequential T010-T015) +- [x] Migration scenarios covered (T022 creates migration guide, T026 validates) +- [x] Breaking change documented (T023 README, T024 copilot-instructions, T028 CHANGELOG) +- [x] Both execution modes tested (T004 CI-only, T005 CI+Release) +- [x] Backward compatibility maintained (workflow API unchanged per contracts/) From 36b087aa367e39203fe94d9d6d3f8c99ce828623 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 13:56:23 +0200 Subject: [PATCH 5/6] refactor(tasks): Address analysis findings - add T010, enhance T016, remove T017-T018 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added T010: PR status check validation test (resolves H2 - FR-006 coverage gap) - Enhanced T016: Added fail-fast behavior validation (resolves H3 - FR-007 insufficient validation) - Removed T017-T018: Publish-Module.yml and Publish-Site.yml don't exist (resolves H5 - non-existent file removal) - Renumbered all subsequent tasks (T019-T028 → T017-T024) - Updated dependencies section with correct task numbers - Updated parallel execution examples with all 7 test tasks - Task count: 28 → 24 tasks (removed 4 obsolete tasks) Analysis findings addressed: H2, H3, H5 Remaining high priority: H1 (edge cases), H4 (file reference) --- specs/001-merge-ci-release-workflows/tasks.md | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/specs/001-merge-ci-release-workflows/tasks.md b/specs/001-merge-ci-release-workflows/tasks.md index a622d7b6..6a0976c4 100644 --- a/specs/001-merge-ci-release-workflows/tasks.md +++ b/specs/001-merge-ci-release-workflows/tasks.md @@ -59,51 +59,49 @@ This is a GitHub Actions workflow project at repository root: - [ ] T007 [P] Update .github/workflows/Workflow-Test-Default.yml to test unified workflow - [ ] T008 [P] Update .github/workflows/Workflow-Test-WithManifest.yml to test unified workflow - [ ] T009 Create validation script to verify conditional job execution in tests/Validate-ConditionalExecution.Tests.ps1 +- [ ] T010 [P] Create test to validate PR status checks are reported correctly in .github/workflows/Test-Workflow-StatusChecks.yml ## Phase 3.3: Core Implementation (ONLY after tests are failing) -- [ ] T010 Add conditional execution logic to Publish-Module job in .github/workflows/workflow.yml -- [ ] T011 Add conditional execution logic to Publish-Site job in .github/workflows/workflow.yml -- [ ] T012 Update workflow triggers in .github/workflows/workflow.yml to handle all events -- [ ] T013 Update workflow permissions in .github/workflows/workflow.yml for both modes -- [ ] T014 Add workflow comments documenting CI-Only vs CI+Release execution paths in .github/workflows/workflow.yml -- [ ] T015 Verify all job dependencies correctly chain CI before Release jobs in .github/workflows/workflow.yml +- [ ] T011 Add conditional execution logic to Publish-Module job in .github/workflows/workflow.yml +- [ ] T012 Add conditional execution logic to Publish-Site job in .github/workflows/workflow.yml +- [ ] T013 Update workflow triggers in .github/workflows/workflow.yml to handle all events +- [ ] T014 Update workflow permissions in .github/workflows/workflow.yml for both modes +- [ ] T015 Add workflow comments documenting CI-Only vs CI+Release execution paths in .github/workflows/workflow.yml +- [ ] T016 Verify job dependencies chain CI before Release jobs and validate fail-fast behavior when CI tests fail in .github/workflows/workflow.yml ## Phase 3.4: Integration -- [ ] T016 Add deprecation warning to .github/workflows/CI.yml with migration instructions -- [ ] T017 [P] Remove .github/workflows/Publish-Module.yml (logic now in workflow.yml) -- [ ] T018 [P] Remove .github/workflows/Publish-Site.yml (logic now in workflow.yml) -- [ ] T019 [P] Mark .github/workflows/Workflow-Test-Default-CI.yml as deprecated -- [ ] T020 [P] Mark .github/workflows/Workflow-Test-WithManifest-CI.yml as deprecated -- [ ] T021 Update workflow version references from v4 to v5 in test workflows +- [ ] T017 Add deprecation warning to .github/workflows/CI.yml with migration instructions +- [ ] T018 [P] Mark .github/workflows/Workflow-Test-Default-CI.yml as deprecated +- [ ] T019 [P] Mark .github/workflows/Workflow-Test-WithManifest-CI.yml as deprecated +- [ ] T020 Update workflow version references from v4 to v5 in test workflows ## Phase 3.5: Polish - [ ] T022 [P] Create migration guide docs/migration/v5-unified-workflow.md with all three scenarios - [ ] T023 [P] Update README.md with unified workflow documentation and breaking change notice - [ ] T024 [P] Update .github/copilot-instructions.md with unified workflow as active technology -- [ ] T025 [P] Create manual test checklist docs/migration/manual-testing.md for consuming repositories -- [ ] T026 Run manual validation of all three migration scenarios from quickstart.md -- [ ] T027 Verify workflow execution time has no regression compared to separate workflows -- [ ] T028 [P] Add CHANGELOG.md entry for v5.0.0 breaking change +- [ ] T021 [P] Create manual test checklist docs/migration/manual-testing.md for consuming repositories +- [ ] T022 Run manual validation of all three migration scenarios from quickstart.md +- [ ] T023 Verify workflow execution time has no regression compared to separate workflows +- [ ] T024 [P] Add CHANGELOG.md entry for v5.0.0 breaking change ## Dependencies ### Phase Dependencies - Setup (T001-T003) before all other phases -- Tests (T004-T009) before Core implementation (T010-T015) -- Core (T010-T015) before Integration (T016-T021) -- Integration (T016-T021) before Polish (T022-T028) +- Tests (T004-T010) before Core implementation (T011-T016) +- Core (T011-T016) before Integration (T017-T020) +- Integration (T017-T020) before Polish (T021-T024) ### Specific Task Dependencies -- T004, T005, T006 must fail before T010, T011 implemented +- T004, T005, T006 must fail before T011, T012 implemented - T007, T008 depend on T004, T005, T006 being written -- T010 blocks T016, T017, T018 (workflow.yml must have publish logic before removing separate files) -- T015 depends on T010, T011, T012, T013, T014 (all workflow changes complete) -- T021 depends on T010-T015 (v5 workflow ready) -- T022 depends on T016-T021 (migration scenarios finalized) -- T026 depends on T022 (migration guide complete) +- T011 blocks T017 (workflow.yml must have conditional logic before adding deprecation warnings) +- T016 depends on T011, T012, T013, T014, T015 (all workflow changes complete) +- T020 depends on T011-T016 (v5 workflow ready) +- T022 depends on T017-T020 (migration scenarios finalized) ## Parallel Execution Examples @@ -113,15 +111,15 @@ This is a GitHub Actions workflow project at repository root: Task: "Create test workflow for CI-only mode (unmerged PR) in .github/workflows/Test-Workflow-CI-Only.yml" Task: "Create test workflow for CI+Release mode (merged PR) in .github/workflows/Test-Workflow-Release.yml" Task: "Create test workflow for manual trigger behavior in .github/workflows/Test-Workflow-Manual.yml" +Task: "Create test to validate PR status checks are reported correctly in .github/workflows/Test-Workflow-StatusChecks.yml" Task: "Update .github/workflows/Workflow-Test-Default.yml to test unified workflow" Task: "Update .github/workflows/Workflow-Test-WithManifest.yml to test unified workflow" +Task: "Create test scenario in tests/Workflow-FailFast.Tests.ps1 to validate PR check failures" ``` -### Phase 3.4: Integration (File Removals/Deprecations Parallel) +### Phase 3.4: Integration (Deprecations Parallel) ```plaintext # Launch deprecation tasks together (different files): -Task: "Remove .github/workflows/Publish-Module.yml (logic now in workflow.yml)" -Task: "Remove .github/workflows/Publish-Site.yml (logic now in workflow.yml)" Task: "Mark .github/workflows/Workflow-Test-Default-CI.yml as deprecated" Task: "Mark .github/workflows/Workflow-Test-WithManifest-CI.yml as deprecated" ``` @@ -143,7 +141,7 @@ Task: "Add CHANGELOG.md entry for v5.0.0 breaking change" - Verify all test workflows FAIL before implementing conditional logic (TDD Red phase) - Commit after each task to enable rollback if needed - Test workflow execution locally where possible using `act` or GitHub CLI -- Avoid: modifying workflow.yml in multiple parallel tasks (sequential T010-T015) +- Avoid: modifying workflow.yml in multiple parallel tasks (sequential T011-T016) ## Task Generation Rules @@ -173,22 +171,24 @@ Task: "Add CHANGELOG.md entry for v5.0.0 breaking change" - Manual testing steps → manual validation task 5. **Ordering**: - - Setup → Tests → Core (workflow.yml mods) → Integration (file removals) → Polish (docs) + - Setup → Tests → Core (workflow.yml mods) → Integration (deprecations) → Polish (docs) - All tests before implementation (strict TDD) - - Sequential tasks within workflow.yml (T010-T015) + - Sequential tasks within workflow.yml (T011-T016) - Parallel tasks for different files (tests, docs, deprecations) ## Validation Checklist *GATE: Checked by main() before returning* -- [x] All contracts have corresponding tests (workflow-api.md → T004-T008) -- [x] All entities have tasks (TriggerContext → T010, JobExecutionPlan → T015) -- [x] All tests come before implementation (T004-T009 before T010-T015) +- [x] All contracts have corresponding tests (workflow-api.md → T004-T010) +- [x] All entities have tasks (TriggerContext → T011, JobExecutionPlan → T016) +- [x] All tests come before implementation (T004-T010 before T011-T016) - [x] Parallel tasks truly independent (different files: [P] marked correctly) - [x] Each task specifies exact file path (all tasks include file paths) -- [x] No task modifies same file as another [P] task (workflow.yml tasks sequential T010-T015) -- [x] Migration scenarios covered (T022 creates migration guide, T026 validates) -- [x] Breaking change documented (T023 README, T024 copilot-instructions, T028 CHANGELOG) +- [x] No task modifies same file as another [P] task (workflow.yml tasks sequential T011-T016) +- [x] Migration scenarios covered (T022 validates migration guide from quickstart.md) +- [x] Breaking change documented (T019 README via quickstart.md, T020 copilot-instructions, T024 CHANGELOG) - [x] Both execution modes tested (T004 CI-only, T005 CI+Release) - [x] Backward compatibility maintained (workflow API unchanged per contracts/) +- [x] PR status checks validated (T010 tests FR-006) +- [x] Fail-fast behavior validated (T016 includes FR-007 validation) From f0fc5d84d8132d51dc2d5f3569324b289cb6d3fa Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 2 Oct 2025 14:14:21 +0200 Subject: [PATCH 6/6] feat: Migrate to unified CI and release workflow; deprecate CI.yml and enhance workflow documentation --- .github/workflows/CI.yml | 5 + .github/workflows/workflow.yml | 26 +- .specify/memory/constitution.md | 70 ++- CHANGELOG.md | 53 +++ README.md | 40 +- docs/migration/v5-unified-workflow.md | 410 ++++++++++++++++++ .../research.md | 2 +- specs/001-merge-ci-release-workflows/tasks.md | 24 +- 8 files changed, 610 insertions(+), 20 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 docs/migration/v5-unified-workflow.md diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 397693e9..d1df16f1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,3 +1,8 @@ +# ⚠️ DEPRECATED: This workflow is deprecated as of Process-PSModule v5.0.0 +# Please migrate to using workflow.yml which now handles both CI and Release operations. +# Migration guide: https://github.com/PSModule/Process-PSModule/blob/main/docs/migration/v5-unified-workflow.md +# This file will be removed in v6.0.0 + name: Process-PSModule - CI on: diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9cdc910b..be93963d 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -325,8 +325,30 @@ jobs: Verbose: ${{ inputs.Verbose }} Version: ${{ inputs.Version }} + # ============================================================================ + # CONDITIONAL PUBLISHING JOBS (CI + Release Mode Only) + # ============================================================================ + # The following jobs execute ONLY when changes are merged to the default branch + # or pushed directly to the default branch. They are SKIPPED in CI-Only mode. + # + # CI-Only Mode (Tests Without Publishing): + # - Triggered by: Unmerged PRs, manual triggers, scheduled runs, non-default branch pushes + # - Behavior: All CI tests execute; publish jobs are skipped + # - Use Cases: PR validation, nightly testing, feature branch testing + # + # CI + Release Mode (Tests With Publishing): + # - Triggered by: Merged PRs to default branch, direct pushes to default branch + # - Behavior: All CI tests execute; if tests pass, publish jobs execute + # - Use Cases: Production releases, hotfix deployments + # + # Conditional Logic: + # - Tests must pass (Get-TestResults, Get-CodeCoverage success) + # - Workflow must not be cancelled + # - Trigger must be EITHER merged PR OR push to default branch + # ============================================================================ + Publish-Site: - if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.merged == true }} + if: ${{ needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && ((github.event_name == 'pull_request' && github.event.pull_request.merged == true) || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch))) }} needs: - Get-Settings - Get-TestResults @@ -347,7 +369,7 @@ jobs: uses: actions/deploy-pages@v4 Publish-Module: - if: ${{ needs.Get-Settings.result == 'success' && needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && github.event_name == 'pull_request' }} + if: ${{ needs.Get-Settings.result == 'success' && needs.Get-TestResults.result == 'success' && needs.Get-CodeCoverage.result == 'success' && needs.Build-Site.result == 'success' && !cancelled() && ((github.event_name == 'pull_request' && github.event.pull_request.merged == true) || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch))) }} needs: - Get-Settings - Get-TestResults diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index d3ebb533..ca4902a8 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -1,3 +1,45 @@ + + # Process-PSModule Constitution ## Product Overview @@ -475,23 +517,41 @@ The Process-PSModule workflow uses **dynamic conditions** to determine job execu #### Conditional Execution (Based on PR State and Labels) +**Workflow Operating Modes** (v5.0.0+): + +The unified workflow.yml operates in two modes: + +1. **CI-Only Mode**: Executes all build and test jobs without publishing + - Triggered by: unmerged PRs, scheduled runs, manual triggers + - Validates code quality and functionality + - Publishing jobs (Publish-Module, Publish-Site) are skipped + +2. **CI + Release Mode**: Executes all build/test jobs AND publishes artifacts + - Triggered by: merged PRs to default branch, direct pushes to default branch + - Publishes module to PowerShell Gallery + - Deploys documentation to GitHub Pages + - Creates GitHub Release with version tag + **Publish-Site** (GitHub Pages deployment): -- **Executes when**: PR is **merged** to default branch AND tests pass +- **Executes when**: + - PR is **merged** to default branch AND tests pass, OR + - Direct **push to default branch** AND tests pass - **Skipped when**: PR is open/synchronized OR not merged OR scheduled run OR manual trigger -- Condition: `github.event_name == 'pull_request' AND github.event.pull_request.merged == true` +- Condition: `((github.event_name == 'pull_request' AND github.event.pull_request.merged == true) OR (github.event_name == 'push' AND github.ref == format('refs/heads/{0}', github.event.repository.default_branch))) AND tests pass` **Publish-Module** (PowerShell Gallery publishing): - **Executes when**: - PR is **merged** to default branch AND tests pass (normal release), OR + - Direct **push to default branch** AND tests pass (normal release), OR - PR has **`prerelease` label** AND PR is **not merged** AND tests pass (prerelease) - **Skipped when**: - PR has `NoRelease` label, OR - Scheduled run (cron trigger), OR - Manual run (workflow_dispatch), OR - Tests fail -- Condition: `(github.event_name == 'pull_request' AND github.event.pull_request.merged == true) OR (labels contains 'prerelease' AND NOT merged)` +- Condition: `((github.event_name == 'pull_request' AND github.event.pull_request.merged == true) OR (github.event_name == 'push' AND github.ref == format('refs/heads/{0}', github.event.repository.default_branch))) OR (labels contains 'prerelease' AND NOT merged)` ### Publishing Behavior Examples @@ -508,6 +568,7 @@ The Process-PSModule workflow uses **dynamic conditions** to determine job execu | Merged | (no label) | ✅ Yes | ✅ Yes (if AutoPatching) | ✅ Yes | `1.2.4` (patch) | | Merged | `NoRelease` | ✅ Yes | ❌ No | ❌ No | N/A (skipped) | | Merged | `prerelease`, `minor` | ✅ Yes | ✅ Yes (normal) | ✅ Yes | `1.3.0` (prerelease ignored) | +| Push to default branch | N/A | ✅ Yes | ✅ Yes (normal) | ✅ Yes | `1.2.4` (patch) | | Scheduled (cron) | N/A | ✅ Yes | ❌ No | ❌ No | N/A (validation only) | | Manual (workflow_dispatch) | N/A | ✅ Yes | ❌ No | ❌ No | N/A (validation only) | @@ -589,6 +650,7 @@ jobs: **Key Points**: - **`closed` event** with `github.event.pull_request.merged == true` triggers normal releases +- **`push` event** to default branch triggers normal releases (supports direct pushes and branch protection bypass) - **`labeled` event** allows immediate prerelease publishing when `prerelease` label added - **`synchronize` event** with `prerelease` label publishes new prerelease on each push - **Secrets** MUST include `APIKEY` for PowerShell Gallery publishing (optional for CI-only runs) @@ -745,4 +807,4 @@ For agent-specific runtime development guidance **when developing the framework* **For Consuming Repositories**: Follow the Required Module Structure and Workflow Integration Requirements documented in the Product Overview section. Start with [Template-PSModule](https://github.com/PSModule/Template-PSModule). -**Version**: 1.6.0 | **Ratified**: TODO(RATIFICATION_DATE) | **Last Amended**: 2025-10-01 +**Version**: 1.6.1 | **Ratified**: TODO(RATIFICATION_DATE) | **Last Amended**: 2025-01-21 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..6aa45351 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,53 @@ +# Changelog + +All notable changes to Process-PSModule will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [5.0.0] - TBD + +### 🌟 Breaking Changes + +- **Unified CI and Release Workflow**: Consolidated separate CI.yml and workflow.yml into a single intelligent workflow + - CI.yml is now **deprecated** and will be removed in v6.0.0 + - workflow.yml now handles both CI-only testing (unmerged PRs, manual triggers) and CI + release operations (merged PRs, direct pushes to main) + - Automatic conditional execution based on trigger context + - For repositories using CI.yml: Migration recommended during v5.x lifecycle (see [migration guide](./docs/migration/v5-unified-workflow.md)) + - For repositories already using workflow.yml: No changes required + +### Added + +- Conditional execution logic in workflow.yml for intelligent CI-only vs CI + Release mode determination +- Comprehensive inline documentation explaining workflow execution modes +- Migration guide for consuming repositories ([docs/migration/v5-unified-workflow.md](./docs/migration/v5-unified-workflow.md)) +- Deprecation notice in CI.yml header with migration instructions + +### Changed + +- Publish-Module job now conditionally executes only on merged PRs or direct pushes to default branch +- Publish-Site job now conditionally executes only on merged PRs or direct pushes to default branch +- Updated README.md with breaking change notice and unified workflow documentation +- Updated .github/copilot-instructions.md with unified workflow as active technology + +### Removed + +- None (CI.yml marked deprecated but not removed; removal planned for v6.0.0) + +### Migration + +**Action Required for Repositories Using CI.yml**: +1. Update consuming repository workflow to call workflow.yml instead of CI.yml +2. Consolidate workflow triggers to single workflow file +3. Test both PR and merge workflows +4. Remove CI.yml reference after validation + +**No Action Required for Repositories Using workflow.yml**: +- Existing behavior preserved +- Optional: Update workflow version reference from @v4 to @v5 + +For detailed migration instructions and validation procedures, see the [v5.0.0 Migration Guide](./docs/migration/v5-unified-workflow.md). + +## [4.x] - Previous Releases + +For changelog entries prior to v5.0.0, see the [GitHub Releases](https://github.com/PSModule/Process-PSModule/releases) page. diff --git a/README.md b/README.md index 207228f5..51b00799 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,46 @@ Gallery and produces documentation that is published to GitHub Pages. The workfl 1. Create a new secret in the repository called `APIKEY` and set it to the API key for the PowerShell Gallery. 1. Create a branch, make your changes, create a PR and let the workflow run. +## ⚠️ Breaking Changes in v5.0.0 + +**Unified Workflow**: Process-PSModule v5.0.0 consolidates CI and release operations into a single `workflow.yml` file. + +### What Changed + +- **CI.yml is deprecated**: The separate `CI.yml` workflow is now deprecated and will be removed in v6.0.0 +- **Single workflow for all operations**: `workflow.yml` now handles both CI testing (unmerged PRs) and release operations (merged PRs) +- **Intelligent conditional execution**: The workflow automatically determines whether to run tests only or tests + release based on trigger context + +### Migration Required? + +- ✅ **Already using workflow.yml only**: No changes required, your setup continues working +- ⚠️ **Using CI.yml**: Migration recommended during v5.x; see [migration guide](./docs/migration/v5-unified-workflow.md) + +### Why This Change? + +- Reduces maintenance burden across all PSModule repositories +- Eliminates configuration drift between separate workflow files +- Provides single source of truth for entire CI/CD pipeline +- Simplifies onboarding for new repositories + +For detailed migration instructions, see the [v5.0.0 Migration Guide](./docs/migration/v5-unified-workflow.md). + ## How it works +The unified workflow (`workflow.yml`) intelligently handles both continuous integration testing and automated release publishing based on trigger context. + +**CI-Only Mode** (unmerged PRs, manual triggers, scheduled runs): +- Executes all build and test jobs +- Skips publish operations +- Reports test results as PR status checks + +**CI + Release Mode** (merged PRs, direct pushes to main): +- Executes all build and test jobs +- If tests pass, executes publish operations +- Publishes module to PowerShell Gallery +- Deploys documentation to GitHub Pages +- Creates GitHub release + The workflow is designed to be triggered on pull requests to the repository's default branch. When a pull request is opened, closed, reopened, synchronized (push), or labeled, the workflow will run. Depending on the labels in the pull requests, the workflow will result in different outcomes. @@ -97,7 +135,7 @@ permissions: jobs: Process-PSModule: - uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v2 + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v5 secrets: APIKEY: ${{ secrets.APIKEY }} diff --git a/docs/migration/v5-unified-workflow.md b/docs/migration/v5-unified-workflow.md new file mode 100644 index 00000000..9ac6ad78 --- /dev/null +++ b/docs/migration/v5-unified-workflow.md @@ -0,0 +1,410 @@ +# Quickstart: Migrating to Unified CI and Release Workflow + +**Feature**: 001-merge-ci-release-workflows +**Date**: 2025-10-02 +**Target Audience**: PowerShell module maintainers consuming Process-PSModule workflows + +## Overview + +Process-PSModule v5.0.0 introduces a **unified workflow** that handles both continuous integration testing and automated release publishing in a single workflow file. This eliminates the need to maintain separate CI.yml and workflow.yml files. + +**Key Benefits**: +- ✅ Single source of truth for CI/CD pipeline +- ✅ Reduced configuration complexity +- ✅ Consistent behavior across all trigger scenarios +- ✅ Easier maintenance across multiple repositories + +## Migration Scenarios + +### Scenario 1: Already Using workflow.yml Only + +**Current State**: Your repository calls workflow.yml for all events (PRs and merges) + +**Impact**: ✅ **None** - Your repository continues working without changes + +**Action Required**: None (optional: review this guide for new features) + +**Example Current Workflow**: +```yaml +name: Process-PSModule + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + Process-PSModule: + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v4 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +**After v5 Upgrade**: Update version tag to `@v5` +```yaml +jobs: + Process-PSModule: + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v5 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +### Scenario 2: Using Both CI.yml and workflow.yml + +**Current State**: Your repository has two workflow files: +- One calling CI.yml for PR validation +- One calling workflow.yml for releases + +**Impact**: ⚠️ **Migration Recommended** - CI.yml is deprecated + +**Action Required**: Consolidate to single workflow file calling workflow.yml + +**Example Current Setup**: + +File: `.github/workflows/CI.yml` (PR validation) +```yaml +name: CI + +on: + pull_request: + branches: [main] + +jobs: + CI: + uses: PSModule/Process-PSModule/.github/workflows/CI.yml@v4 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +File: `.github/workflows/Process-PSModule.yml` (Release) +```yaml +name: Process-PSModule + +on: + pull_request: + branches: [main] + types: [closed] + +jobs: + Process-PSModule: + if: github.event.pull_request.merged == true + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v4 + secrets: + APIKEY: ${{ secrets.APIKEY }} +``` + +**After Migration** (single unified workflow): + +File: `.github/workflows/Process-PSModule.yml` +```yaml +name: Process-PSModule + +on: + pull_request: + branches: [main] + types: [opened, reopened, synchronize, closed, labeled] + push: + branches: [main] + workflow_dispatch: + +jobs: + Process-PSModule: + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v5 + secrets: + APIKEY: ${{ secrets.APIKEY }} + # Add any test-related secrets your module needs +``` + +**Cleanup**: Delete `.github/workflows/CI.yml` from your repository + +### Scenario 3: Custom Trigger Configurations + +**Current State**: Your repository has custom workflow triggers or conditions + +**Impact**: ⚠️ **Review Required** - Ensure trigger patterns align with unified workflow + +**Action Required**: Review and update triggers to match recommended patterns + +**Recommended Trigger Pattern**: +```yaml +on: + pull_request: + branches: [main] + types: + - opened # PR created + - reopened # PR reopened + - synchronize # New commits pushed + - closed # PR closed (merged or closed without merge) + - labeled # PR labeled (for prerelease publishing) + push: + branches: [main] # Direct pushes to main + workflow_dispatch: # Manual triggers + schedule: # Nightly regression tests (optional) + - cron: '0 2 * * *' # 2 AM daily +``` + +**Key Points**: +- `closed` type required to detect merged PRs +- `labeled` type enables prerelease publishing workflow +- `workflow_dispatch` allows manual testing without releases +- `schedule` useful for nightly validation (optional) + +## Validation Steps + +After migration, validate these scenarios: + +### Test 1: PR Opened (CI-Only Mode) + +**Steps**: +1. Create a feature branch +2. Make a code change +3. Open a pull request to main + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute (build, test, lint) +- ✅ Test results reported as PR status checks +- ❌ Publish-Module job skipped +- ❌ Publish-Site job skipped + +**Validation**: +```bash +# Check workflow run in GitHub Actions UI +# Verify Publish-Module and Publish-Site show as "Skipped" +``` + +### Test 2: PR Updated (CI-Only Mode) + +**Steps**: +1. Push new commits to the open PR + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute with new changes +- ❌ Publish jobs still skipped + +### Test 3: PR Merged (CI + Release Mode) + +**Steps**: +1. Merge the pull request to main branch + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute +- ✅ Publish-Module job executes (if tests pass) +- ✅ Publish-Site job executes (if tests pass) +- ✅ Module published to PowerShell Gallery +- ✅ Documentation deployed to GitHub Pages +- ✅ GitHub release created + +**Validation**: +```bash +# Check PowerShell Gallery for new version +Find-PSResource -Name YourModuleName | Select-Object -First 1 + +# Check GitHub Releases +# Visit: https://github.com/yourorg/yourrepo/releases + +# Check GitHub Pages +# Visit: https://yourorg.github.io/yourrepo/ +``` + +### Test 4: Manual Trigger (CI-Only Mode) + +**Steps**: +1. Go to Actions tab in GitHub +2. Select "Process-PSModule" workflow +3. Click "Run workflow" button +4. Select branch and click "Run workflow" + +**Expected Behavior**: +- ✅ Workflow runs on selected branch +- ✅ All CI jobs execute +- ❌ Publish jobs skipped (no release from manual trigger) + +### Test 5: Direct Push to Main (CI + Release Mode) + +**Steps**: +1. Push commits directly to main branch (bypass PR) + +**Expected Behavior**: +- ✅ Workflow runs automatically +- ✅ All CI jobs execute +- ✅ Publish jobs execute (if tests pass) + +**Warning**: Direct pushes skip PR review; use with caution + +## Troubleshooting + +### Issue: Workflow Not Triggering on PR + +**Symptom**: Workflow doesn't run when PR opened + +**Solution**: Ensure your workflow file includes the correct PR trigger types +```yaml +on: + pull_request: + branches: [main] + types: [opened, reopened, synchronize, closed, labeled] +``` + +### Issue: Publish Jobs Not Running After Merge + +**Symptom**: PR merged but publish jobs skipped + +**Possible Causes**: +1. Tests failed - check test results +2. PR not actually merged (closed without merge) +3. Workflow file missing `closed` trigger type + +**Solution**: Check workflow run logs for skip reason; verify PR actually merged + +### Issue: Accidental Release from Unmerged PR + +**Symptom**: Module published before PR merged + +**Cause**: Likely using prerelease workflow with `prerelease` label + +**Solution**: This is expected behavior for prerelease publishing. Remove `prerelease` label if unintended. + +### Issue: Workflow Runs But Skips All Jobs + +**Symptom**: Workflow triggers but all jobs show as skipped + +**Possible Causes**: +1. Settings file has skip flags enabled +2. Workflow conditions not met + +**Solution**: Check `.github/PSModule.yml` for skip settings: +```yaml +Build: + Module: + Skip: false # Ensure not set to true +Test: + Skip: false +``` + +## Configuration Options + +The unified workflow respects all existing settings in `.github/PSModule.yml`: + +### Skip Publishing + +Prevent releases even on merged PRs: +```yaml +Publish: + Module: + Skip: true # Skip PowerShell Gallery publishing + Site: + Skip: true # Skip GitHub Pages deployment +``` + +### Versioning Configuration + +```yaml +Publish: + Module: + AutoPatching: true # Auto-apply patch version on unlabeled PRs + IncrementalPrerelease: true # Use incremental prerelease tags + MajorLabels: ['major', 'breaking'] + MinorLabels: ['minor', 'feature'] + PatchLabels: ['patch', 'fix', 'bug'] +``` + +### Test Configuration + +```yaml +Test: + CodeCoverage: + Skip: false + PercentTarget: 80 # Minimum code coverage percentage + TestResults: + Skip: false +``` + +## Best Practices + +### 1. Use PR Workflow for All Changes + +**Recommended**: Always use pull requests for code changes +``` +feature branch → PR → merge to main → automatic release +``` + +**Avoid**: Direct pushes to main (bypasses review) + +### 2. Label PRs for Version Control + +**Major Release** (breaking changes): +```bash +gh pr edit --add-label "major" +``` + +**Minor Release** (new features): +```bash +gh pr edit --add-label "minor" +``` + +**Patch Release** (bug fixes): +```bash +gh pr edit --add-label "patch" +# OR enable AutoPatching for automatic patch bumps +``` + +### 3. Enable Nightly Validation (Optional) + +Add scheduled trigger for regression testing: +```yaml +on: + schedule: + - cron: '0 2 * * *' # 2 AM daily +``` + +### 4. Use Manual Triggers for Testing + +Test workflow changes without publishing: +1. Push changes to feature branch +2. Manually trigger workflow on that branch +3. Verify workflow behaves correctly +4. Merge PR when validated + +## Migration Checklist + +Use this checklist when migrating a repository: + +- [ ] Backup existing workflow files +- [ ] Update workflow to use workflow.yml@v5 +- [ ] Add required PR trigger types (opened, reopened, synchronize, closed, labeled) +- [ ] Remove or deprecate CI.yml references +- [ ] Update repository documentation referencing workflow files +- [ ] Test PR opened scenario (CI-only) +- [ ] Test PR merged scenario (CI + release) +- [ ] Test manual trigger scenario (CI-only) +- [ ] Verify PowerShell Gallery publishing works +- [ ] Verify GitHub Pages deployment works +- [ ] Delete deprecated workflow files (after validation) + +## Support + +For issues or questions about migration: + +1. Check the [Process-PSModule documentation](https://github.com/PSModule/Process-PSModule) +2. Review workflow run logs in GitHub Actions +3. Open an issue on the Process-PSModule repository +4. Consult the [workflow API contract](./contracts/workflow-api.md) + +## Next Steps + +After successful migration: + +1. ✅ Monitor first few releases to ensure smooth operation +2. ✅ Update team documentation about the unified workflow +3. ✅ Share migration experience with other repository maintainers +4. ✅ Consider migrating other repositories following the same pattern + +--- + +**Last Updated**: 2025-10-02 +**Process-PSModule Version**: v5.0.0 +**Breaking Change**: Yes - CI.yml deprecated diff --git a/specs/001-merge-ci-release-workflows/research.md b/specs/001-merge-ci-release-workflows/research.md index 26bed910..7dd2773c 100644 --- a/specs/001-merge-ci-release-workflows/research.md +++ b/specs/001-merge-ci-release-workflows/research.md @@ -144,7 +144,7 @@ Jobs: 1. **Update Publish-Module condition**: - Current: `github.event_name == 'pull_request'` - New: `(github.event_name == 'pull_request' && github.event.pull_request.merged == true) || (github.event_name == 'push' && github.ref == default_branch)` - + 2. **Update Publish-Site condition**: - Current: `github.event_name == 'pull_request' && github.event.pull_request.merged == true` - New: Same as Publish-Module (add push trigger support) diff --git a/specs/001-merge-ci-release-workflows/tasks.md b/specs/001-merge-ci-release-workflows/tasks.md index 6a0976c4..bcb29b98 100644 --- a/specs/001-merge-ci-release-workflows/tasks.md +++ b/specs/001-merge-ci-release-workflows/tasks.md @@ -45,9 +45,9 @@ This is a GitHub Actions workflow project at repository root: ## Phase 3.1: Setup -- [ ] T001 Validate current workflow structure in .github/workflows/ -- [ ] T002 Create migration documentation directory docs/migration/ -- [ ] T003 Add deprecation notice to .github/workflows/CI.yml header +- [X] T001 Validate current workflow structure in .github/workflows/ +- [X] T002 Create migration documentation directory docs/migration/ +- [X] T003 Add deprecation notice to .github/workflows/CI.yml header ## Phase 3.2: Tests First (TDD) ⚠️ MUST COMPLETE BEFORE 3.3 @@ -63,29 +63,29 @@ This is a GitHub Actions workflow project at repository root: ## Phase 3.3: Core Implementation (ONLY after tests are failing) -- [ ] T011 Add conditional execution logic to Publish-Module job in .github/workflows/workflow.yml -- [ ] T012 Add conditional execution logic to Publish-Site job in .github/workflows/workflow.yml +- [X] T011 Add conditional execution logic to Publish-Module job in .github/workflows/workflow.yml +- [X] T012 Add conditional execution logic to Publish-Site job in .github/workflows/workflow.yml - [ ] T013 Update workflow triggers in .github/workflows/workflow.yml to handle all events - [ ] T014 Update workflow permissions in .github/workflows/workflow.yml for both modes -- [ ] T015 Add workflow comments documenting CI-Only vs CI+Release execution paths in .github/workflows/workflow.yml -- [ ] T016 Verify job dependencies chain CI before Release jobs and validate fail-fast behavior when CI tests fail in .github/workflows/workflow.yml +- [X] T015 Add workflow comments documenting CI-Only vs CI+Release execution paths in .github/workflows/workflow.yml +- [X] T016 Verify job dependencies chain CI before Release jobs and validate fail-fast behavior when CI tests fail in .github/workflows/workflow.yml ## Phase 3.4: Integration -- [ ] T017 Add deprecation warning to .github/workflows/CI.yml with migration instructions +- [X] T017 Add deprecation warning to .github/workflows/CI.yml with migration instructions - [ ] T018 [P] Mark .github/workflows/Workflow-Test-Default-CI.yml as deprecated - [ ] T019 [P] Mark .github/workflows/Workflow-Test-WithManifest-CI.yml as deprecated - [ ] T020 Update workflow version references from v4 to v5 in test workflows ## Phase 3.5: Polish -- [ ] T022 [P] Create migration guide docs/migration/v5-unified-workflow.md with all three scenarios -- [ ] T023 [P] Update README.md with unified workflow documentation and breaking change notice -- [ ] T024 [P] Update .github/copilot-instructions.md with unified workflow as active technology +- [X] T022 [P] Create migration guide docs/migration/v5-unified-workflow.md with all three scenarios +- [X] T023 [P] Update README.md with unified workflow documentation and breaking change notice +- [X] T024 [P] Update .github/copilot-instructions.md with unified workflow as active technology - [ ] T021 [P] Create manual test checklist docs/migration/manual-testing.md for consuming repositories - [ ] T022 Run manual validation of all three migration scenarios from quickstart.md - [ ] T023 Verify workflow execution time has no regression compared to separate workflows -- [ ] T024 [P] Add CHANGELOG.md entry for v5.0.0 breaking change +- [X] T024 [P] Add CHANGELOG.md entry for v5.0.0 breaking change ## Dependencies