|
| 1 | +# Feature Specification: Local GitHub Composite Action for BeforeAll/AfterAll Test Scripts |
| 2 | + |
| 3 | +**Feature Branch**: `001-building-on-this` |
| 4 | +**Created**: October 1, 2025 |
| 5 | +**Status**: Draft |
| 6 | +**Input**: User description: "Building on this branch, we want to add a local github action (composite) to run the BeforeAll and AfterAll |
| 7 | +scripts and call this from the workflows ci.yml and workflow (via Test-ModuleLocal)." |
| 8 | + |
| 9 | +## Execution Flow (main) |
| 10 | +``` |
| 11 | +1. Parse user description from Input |
| 12 | + → Feature request identified: Create reusable composite action for setup/teardown scripts |
| 13 | +2. Extract key concepts from description |
| 14 | + → Actors: CI/CD workflows, test runners, module developers |
| 15 | + → Actions: Execute BeforeAll.ps1 scripts before tests, AfterAll.ps1 scripts after tests |
| 16 | + → Data: Test directories, setup/teardown scripts, environment secrets |
| 17 | + → Constraints: Must integrate with existing Test-ModuleLocal workflow |
| 18 | +3. Unclear aspects identified: |
| 19 | + → Action location and naming convention - assumed ✓ |
| 20 | + → Error handling differences from inline implementation - specified in requirements |
| 21 | + → Additional inputs/outputs beyond current inline version - specified in requirements |
| 22 | +4. User Scenarios & Testing section completed |
| 23 | + → Primary flow: Workflow calls composite action for setup/teardown |
| 24 | + → Edge cases: Missing scripts, script failures, multiple test directories |
| 25 | +5. Functional Requirements generated |
| 26 | + → All requirements are testable |
| 27 | + → No ambiguous requirements requiring clarification |
| 28 | +6. Key Entities identified |
| 29 | + → Composite action, test directories, setup/teardown scripts |
| 30 | +7. Review Checklist status |
| 31 | + → No implementation details included (GitHub Actions syntax is configuration, not implementation) |
| 32 | + → Focused on behavior and integration requirements |
| 33 | + → All sections completed with clear acceptance criteria |
| 34 | +8. Return: SUCCESS (spec ready for planning) |
| 35 | +``` |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## ⚡ Quick Guidelines |
| 40 | +- ✅ Focus on WHAT users need and WHY |
| 41 | +- ❌ Avoid HOW to implement (no tech stack, APIs, code structure) |
| 42 | +- 👥 Written for business stakeholders, not developers |
| 43 | + |
| 44 | +--- |
| 45 | + |
| 46 | +## Clarifications |
| 47 | + |
| 48 | +### Session 2025-10-01 |
| 49 | +- Q: When multiple BeforeAll.ps1 scripts exist in nested directories, what execution order should be guaranteed? → A: Scripts only supported in root tests folder - no nested directory support. |
| 50 | +- Q: Which runner OS should BeforeAll-ModuleLocal and AfterAll-ModuleLocal jobs use? → A: ubuntu-latest only - Keep current behavior, actions run on Linux only. |
| 51 | +- Q: What level of detail is required for the output showing whether scripts were found and executed? → A: Match current - Same output format as current inline implementation in Test-ModuleLocal.yml. |
| 52 | +- Q: Should separate actions be created for BeforeAll and AfterAll, or a different approach? → A: Single action with mode parameter (before/after modes). |
| 53 | +- Q: What should the composite action be named and where should it be located? → A: Setup-Test - `.github/actions/setup-test/action.yml`. |
| 54 | + |
| 55 | +--- |
| 56 | + |
| 57 | +## User Scenarios & Testing |
| 58 | + |
| 59 | +### Primary User Story |
| 60 | +As a module developer using the Process-PSModule framework, I want the BeforeAll and AfterAll test setup/teardown logic to be encapsulated in a |
| 61 | +reusable local composite action so that the Test-ModuleLocal workflow is cleaner, more maintainable, and the logic can potentially be reused in other |
| 62 | +workflows without duplication. |
| 63 | + |
| 64 | +Currently, the BeforeAll-ModuleLocal and AfterAll-ModuleLocal jobs in Test-ModuleLocal.yml contain inline PowerShell scripts that locate and execute BeforeAll.ps1 and AfterAll.ps1 scripts in the root tests directory with environment variables. |
| 65 | + |
| 66 | +This logic should be extracted into a single local composite action with a mode parameter (before/after) that both Test-ModuleLocal.yml and ci.yml can reference. |
| 67 | + |
| 68 | +### Acceptance Scenarios |
| 69 | + |
| 70 | +1. **Given** the local composite action exists with mode parameter set to "before" and a BeforeAll.ps1 script is in the root tests folder, **When** Test-ModuleLocal workflow executes the BeforeAll-ModuleLocal job, **Then** it should call the composite action which discovers and executes the BeforeAll.ps1 script with access to all required secrets and environment variables. |
| 71 | + |
| 72 | +2. **Given** the local composite action exists with mode parameter set to "after" and an AfterAll.ps1 script is in the root tests folder, **When** Test-ModuleLocal workflow executes the AfterAll-ModuleLocal job (even if tests fail), **Then** it should call the composite action which discovers and executes the AfterAll.ps1 script and continues execution even if the script fails. |
| 73 | + |
| 74 | +3. **Given** no tests directory exists in the repository, **When** the composite action runs in either mode, **Then** it should exit successfully with a clear message indicating no tests were found. |
| 75 | + |
| 76 | +4. **Given** a tests directory exists but no BeforeAll.ps1 script is present, **When** the composite action runs in "before" mode, **Then** it should exit successfully with a message indicating no setup script was found. |
| 77 | + |
| 78 | +5. **Given** a tests directory exists but no AfterAll.ps1 script is present, **When** the composite action runs in "after" mode, **Then** it should exit successfully with a message indicating no teardown script was found. |
| 79 | + |
| 80 | +6. **Given** a BeforeAll.ps1 script in the root tests folder fails during execution, **When** the composite action runs in "before" mode, **Then** it should fail the workflow job and provide clear error output indicating the script failed. |
| 81 | + |
| 82 | +7. **Given** an AfterAll.ps1 script in the root tests folder fails during execution, **When** the composite action runs in "after" mode, **Then** it should log a warning but complete successfully to ensure the workflow can finish. |
| 83 | + |
| 84 | +8. **Given** the composite action is called from Test-ModuleLocal.yml, **When** it needs access to test secrets (TEST_APP_*, TEST_USER_*, GITHUB_TOKEN), **Then** those secrets should be available to the BeforeAll/AfterAll scripts through environment variables regardless of mode. |
| 85 | + |
| 86 | +### Edge Cases |
| 87 | + |
| 88 | +- What happens when the composite action is called from a workflow that requires a different runner OS? |
| 89 | + - **Answer**: The composite actions run on ubuntu-latest runners as part of BeforeAll-ModuleLocal and AfterAll-ModuleLocal jobs; the actions themselves are not directly portable to other OS runners |
| 90 | + |
| 91 | +- What happens when a script takes an exceptionally long time to execute? |
| 92 | + - **Answer**: Standard GitHub Actions timeout limits apply; workflows should set appropriate timeout-minutes if needed |
| 93 | + |
| 94 | +- What happens when BeforeAll.ps1 or AfterAll.ps1 scripts exist in nested subdirectories under tests/? |
| 95 | + - **Answer**: Nested scripts are not supported; only scripts in the root tests folder (tests/BeforeAll.ps1, tests/AfterAll.ps1) are discovered and executed |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +## Requirements |
| 100 | + |
| 101 | +### Functional Requirements |
| 102 | + |
| 103 | +- **FR-001**: System MUST provide a single local composite action that can execute either BeforeAll.ps1 or AfterAll.ps1 scripts based on a mode parameter. |
| 104 | + |
| 105 | +- **FR-002**: The composite action MUST accept a required "mode" input parameter with allowed values of "before" or "after". |
| 106 | + |
| 107 | +- **FR-003**: When mode is "before", the action MUST look for BeforeAll.ps1 only in the root 'tests' folder (tests/BeforeAll.ps1). |
| 108 | + |
| 109 | +- **FR-004**: When mode is "after", the action MUST look for AfterAll.ps1 only in the root 'tests' folder (tests/AfterAll.ps1). |
| 110 | + |
| 111 | +- **FR-005**: The composite action MUST change to the tests directory before script execution and restore the previous directory afterward. |
| 112 | + |
| 113 | +- **FR-006**: When mode is "before", the action MUST fail the workflow job if the BeforeAll.ps1 script fails, providing clear error messages. |
| 114 | + |
| 115 | +- **FR-007**: When mode is "after", the action MUST log warnings for script failures but complete successfully to allow workflow cleanup to finish. |
| 116 | + |
| 117 | +- **FR-008**: The composite action MUST exit successfully with informative messages when no tests directory exists, regardless of mode. |
| 118 | + |
| 119 | +- **FR-009**: When mode is "before" and no BeforeAll.ps1 script exists, the action MUST exit successfully with an informative message. |
| 120 | + |
| 121 | +- **FR-010**: When mode is "after" and no AfterAll.ps1 script exists, the action MUST exit successfully with an informative message. |
| 122 | + |
| 123 | +- **FR-011**: The composite action MUST accept all environment secrets currently used in Test-ModuleLocal workflow (TEST_APP_ENT_CLIENT_ID, TEST_APP_ENT_PRIVATE_KEY, TEST_APP_ORG_CLIENT_ID, TEST_APP_ORG_PRIVATE_KEY, TEST_USER_ORG_FG_PAT, TEST_USER_USER_FG_PAT, TEST_USER_PAT, GITHUB_TOKEN). |
| 124 | + |
| 125 | +- **FR-012**: The composite action MUST accept standard configuration inputs: Debug, Verbose, Prerelease, Version, WorkingDirectory. |
| 126 | + |
| 127 | +- **FR-013**: The composite action MUST provide output matching the current inline implementation format, including LogGroup wrappers, status messages for script discovery, execution confirmation, and completion status. |
| 128 | + |
| 129 | +- **FR-014**: Test-ModuleLocal.yml workflow MUST replace its inline BeforeAll and AfterAll logic with calls to the new composite action with appropriate mode parameters. |
| 130 | + |
| 131 | +- **FR-015**: The composite action MUST be stored at `.github/actions/setup-test/action.yml`. |
| 132 | + |
| 133 | +- **FR-016**: The composite action MUST support execution on ubuntu-latest runners where the BeforeAll-ModuleLocal and AfterAll-ModuleLocal jobs run. |
| 134 | + |
| 135 | +- **FR-017**: The composite action MUST use PSModule/GitHub-Script@v1 for executing PowerShell logic to maintain consistency with current implementation. |
| 136 | + |
| 137 | +- **FR-018**: The composite action MUST use PSModule/Install-PSModuleHelpers@v1 to ensure required helper modules are available. |
| 138 | + |
| 139 | +- **FR-019**: When called with mode "after", the workflow job MUST always execute regardless of previous job failures (if: always() condition). |
| 140 | + |
| 141 | +- **FR-020**: The composite action MUST maintain the same functional behavior as the current inline implementation in Test-ModuleLocal.yml for root-level scripts. |
| 142 | + |
| 143 | +### Key Entities |
| 144 | + |
| 145 | +- **Local Composite Action (Setup-Test)**: A reusable GitHub Actions composite action that encapsulates the logic for discovering and executing either BeforeAll.ps1 or AfterAll.ps1 scripts based on a mode parameter. Located at `.github/actions/setup-test/action.yml`. Accepts a required mode input ("before" or "after"), along with configuration and secrets inputs. Uses GitHub-Script action for PowerShell execution. Behavior changes based on mode: "before" mode fails on script errors, "after" mode continues on errors. |
| 146 | + |
| 147 | +- **Mode Parameter**: An input parameter that controls which script the action looks for and how it handles errors. Valid values: "before" (looks for BeforeAll.ps1, fails on errors) or "after" (looks for AfterAll.ps1, continues on errors). |
| 148 | + |
| 149 | +- **Test Directory**: The root 'tests' folder in the repository that may contain optional BeforeAll.ps1 or AfterAll.ps1 scripts. Nested subdirectories are not searched for these scripts. |
| 150 | + |
| 151 | +- **BeforeAll.ps1 Script**: An optional PowerShell script located at tests/BeforeAll.ps1 that runs once before all test matrix jobs to set up the test environment (e.g., deploy infrastructure, initialize test data). Executed when the composite action is called with mode="before". Executed with full access to environment secrets. Failures halt the testing workflow. |
| 152 | + |
| 153 | +- **AfterAll.ps1 Script**: An optional PowerShell script located at tests/AfterAll.ps1 that runs once after all test matrix jobs complete to clean up the test environment (e.g., remove test resources, cleanup databases). Executed when the composite action is called with mode="after". Executed with full access to environment secrets. Failures are logged but do not prevent workflow completion. |
| 154 | + |
| 155 | +--- |
| 156 | + |
| 157 | +## Review & Acceptance Checklist |
| 158 | + |
| 159 | +### Content Quality |
| 160 | +- [x] No implementation details (languages, frameworks, APIs) |
| 161 | +- [x] Focused on user value and business needs |
| 162 | +- [x] Written for non-technical stakeholders |
| 163 | +- [x] All mandatory sections completed |
| 164 | + |
| 165 | +### Requirement Completeness |
| 166 | +- [x] No [NEEDS CLARIFICATION] markers remain |
| 167 | +- [x] Requirements are testable and unambiguous |
| 168 | +- [x] Success criteria are measurable |
| 169 | +- [x] Scope is clearly bounded |
| 170 | +- [x] Dependencies and assumptions identified |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +## Execution Status |
| 175 | + |
| 176 | +- [x] User description parsed |
| 177 | +- [x] Key concepts extracted |
| 178 | +- [x] Ambiguities marked (none requiring clarification) |
| 179 | +- [x] User scenarios defined |
| 180 | +- [x] Requirements generated |
| 181 | +- [x] Entities identified |
| 182 | +- [x] Review checklist passed |
| 183 | + |
| 184 | +--- |
| 185 | + |
| 186 | +## Additional Context |
| 187 | + |
| 188 | +### Integration Points |
| 189 | +- **Test-ModuleLocal.yml**: Primary workflow that will consume both composite actions |
| 190 | +- **ci.yml**: Main CI workflow that orchestrates Test-ModuleLocal.yml |
| 191 | +- **Existing Actions**: PSModule/GitHub-Script@v1 and PSModule/Install-PSModuleHelpers@v1 used by composite actions |
| 192 | + |
| 193 | +### Assumptions |
| 194 | +- The composite actions will be created as local actions within the repository (not published separately) |
| 195 | +- Composite action files will follow GitHub Actions composite action specification |
| 196 | +- The current inline logic in Test-ModuleLocal.yml is correct and complete |
| 197 | +- No changes to the behavior of BeforeAll/AfterAll script execution are desired, only encapsulation |
| 198 | + |
| 199 | +### Success Criteria |
| 200 | +- Test-ModuleLocal workflow is cleaner with reduced duplication |
| 201 | +- BeforeAll and AfterAll logic can be tested and maintained independently |
| 202 | +- All existing tests continue to pass with identical behavior |
| 203 | +- Workflow execution time remains the same or improves |
| 204 | +- Other workflows can reuse these composite actions if needed in the future |
0 commit comments