diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 69ca426a..6baa4d44 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -1,18 +1,18 @@ name: Integration Tests # Cloud track + Server (Data Center, Dockerized) track. The two jobs share -# this workflow's nightly cron and dispatch but are otherwise independent: +# this workflow's weekly cron and dispatch but are otherwise independent: # Cloud runs against a live Jira Cloud instance via shared org credentials, # Server boots moveworkforward/atlas-run-standalone:jira-11 with # docker-compose and provisions the fixture project + user from scratch. # # Per-PR Cloud coverage is the smoke_tests job in ci.yml; per-PR Server # coverage is the Server-tagged unit tests in ci.yml. The full suites here -# only run on the cron and on explicit dispatch because the Cloud full +# only run weekly and on explicit dispatch because the Cloud full # suite burns API quota and the Server cold boot is ~25 min. on: schedule: - - cron: "0 5 * * *" + - cron: "0 5 * * 0" workflow_dispatch: inputs: track: @@ -79,7 +79,7 @@ jobs: # # Because this workflow only runs on the cron + manual dispatch, the # Server job is intentionally NOT marked continue-on-error: a red - # nightly is a real signal that either the upstream image has drifted + # weekly run is a real signal that either the upstream image has drifted # or a Server-track regression has slipped in, and we want that noise. # Boot budget: pulling the ~1.2 GB image (~1 min on a warm runner), Maven # dependency verification (~3 min), Tomcat 10.1.44 startup + jira.war diff --git a/Tests/Integration/README.md b/Tests/Integration/README.md index 15610e97..eb823159 100644 --- a/Tests/Integration/README.md +++ b/Tests/Integration/README.md @@ -72,8 +72,8 @@ If `TestIntegrationServer` fails before teardown, it captures `jira-container.lo | Workflow / Job | Trigger | Notes | | ---------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ci.yml` → `smoke_tests` (Cloud) | every PR + every push to `master` | Skipped on fork / Dependabot PRs (no secrets); gates `release.yml` via the `CI Result` aggregator (`workflow_conclusion: success`) | -| `integration_tests.yml` → `cloud_integration_tests` | `0 5 * * *` + manual `workflow_dispatch` | Full Cloud suite — scheduled + manual only; PR-level coverage is the smoke job above | -| `integration_tests.yml` → `server_integration_tests` | `0 5 * * *` + manual `workflow_dispatch` | Never on PRs — ~25 min cold boot is too expensive to gate every PR on; PR-level Server coverage comes from the Server-tagged unit tests in `ci.yml`. Jira boot dominates wall time | +| `integration_tests.yml` → `cloud_integration_tests` | `0 5 * * 0` + manual `workflow_dispatch` | Full Cloud suite — weekly + manual only; PR-level coverage is the smoke job above | +| `integration_tests.yml` → `server_integration_tests` | `0 5 * * 0` + manual `workflow_dispatch` | Never on PRs — ~25 min cold boot is too expensive to gate every PR on; PR-level Server coverage comes from the Server-tagged unit tests in `ci.yml`. Jira boot dominates wall time | ## Prerequisites @@ -400,7 +400,7 @@ Context "Write Operations" -Skip:($fixtures.ReadOnly) { ## CI/CD -Cloud smoke runs as part of the standard `.github/workflows/ci.yml` pipeline; the full Cloud suite and the full Server (Data Center, Dockerized) suite share `.github/workflows/integration_tests.yml`, which fires on a nightly cron and on manual dispatch. +Cloud smoke runs as part of the standard `.github/workflows/ci.yml` pipeline; the full Cloud suite and the full Server (Data Center, Dockerized) suite share `.github/workflows/integration_tests.yml`, which runs weekly and on manual dispatch. ### Workflow Triggers @@ -409,7 +409,7 @@ Cloud smoke runs as part of the standard `.github/workflows/ci.yml` pipeline; th | Pull Request (first-party) | ✅ | ❌ — use `workflow_dispatch` to opt in | ❌ — use `workflow_dispatch` to opt in | | Pull Request (fork / Dependabot) | ⚪ skipped (no secrets) | ❌ | ❌ | | Push to `master` | ✅ | ❌ | ❌ | -| Nightly (5 AM UTC) | — | ✅ | ✅ | +| Weekly (Sunday at 5 AM UTC) | — | ✅ | ✅ | | Manual (`workflow_dispatch`) | re-run via Actions UI | ✅ — pass `track=cloud` (or `both`) | ✅ — pass `track=server` (or `both`) | ### Required Secrets @@ -447,7 +447,7 @@ For **first-party PR branches** (those on `AtlassianPS/JiraPS` itself), the bran - **No build required**: tests run directly against source for speed. - **Parallel execution**: Cloud uses `ThrottleLimit=6`; Server uses `ThrottleLimit=2` (halved because the AMPS/H2 backend serialises Lucene write commits — see the inline comment on the `server_integration_tests` job for the contention details). -- **Concurrency control**: nightly + dispatched runs share one concurrency group with `cancel-in-progress: false`, so an in-flight run is never killed by the next cron tick or a dispatch retry. +- **Concurrency control**: weekly + dispatched runs share one concurrency group with `cancel-in-progress: false`, so an in-flight run is never killed by a dispatch retry. - **NUnit results artifacts**: `Cloud-Integration-Tests` and `Server-Integration-Tests` (each containing `Test-Integration.xml`); the Server job additionally uploads `Server-Jira-Container-Logs` for post-mortem on failures. ## Troubleshooting diff --git a/Tests/Integration/Server.Integration.Tests.ps1 b/Tests/Integration/Server.Integration.Tests.ps1 index aef73d38..b8212cab 100644 --- a/Tests/Integration/Server.Integration.Tests.ps1 +++ b/Tests/Integration/Server.Integration.Tests.ps1 @@ -17,7 +17,7 @@ .NOTES Tagged 'Integration', 'Smoke', 'Server' - this IS the smoke test for the Server track and is the first thing the `server_integration_tests` job in - integration_tests.yml runs (nightly + manual workflow_dispatch only; the + integration_tests.yml runs (weekly + manual workflow_dispatch only; the Server job is not wired up to PRs because the ~25 min cold-boot cost is too expensive to gate every PR on). #> diff --git a/Tests/README.md b/Tests/README.md index 2df41845..afde9898 100644 --- a/Tests/README.md +++ b/Tests/README.md @@ -595,7 +595,7 @@ Cloud integration coverage is split across two workflows: - **Smoke tests** (`ci.yml`, `smoke_tests` job): Run on every first-party PR + every push to `master`. Skipped on fork / Dependabot PRs (no secrets). Gates `release.yml` via the `CI Result` sentinel. - **Full integration tests** (`integration_tests.yml`): two parallel jobs — `cloud_integration_tests` and `server_integration_tests` (Dockerized Jira DC). Run on: - - Nightly schedule (5 AM UTC) — both jobs. + - Weekly schedule (Sunday at 5 AM UTC) — both jobs. - Manual trigger (`workflow_dispatch`) — use this to run the full suite against an in-flight PR branch; pass `track=cloud`, `track=server`, or `track=both` (default `both`). Required GitHub Secrets: diff --git a/Tests/Tools/WorkflowTriggers.Unit.Tests.ps1 b/Tests/Tools/WorkflowTriggers.Unit.Tests.ps1 new file mode 100644 index 00000000..8bed4e32 --- /dev/null +++ b/Tests/Tools/WorkflowTriggers.Unit.Tests.ps1 @@ -0,0 +1,15 @@ +#requires -modules @{ ModuleName = "Pester"; ModuleVersion = "5.7"; MaximumVersion = "5.999" } + +Describe 'GitHub Actions workflow triggers' -Tag Unit { + BeforeAll { + . "$PSScriptRoot/../Helpers/TestTools.ps1" + $script:workflowRoot = Join-Path (Resolve-ProjectRoot) '.github/workflows' + } + + It 'runs integration tests weekly and on demand' { + $workflow = Get-Content (Join-Path $script:workflowRoot 'integration_tests.yml') -Raw + + $workflow | Should -Match 'cron:\s*"0 5 \* \* 0"' + $workflow | Should -Match 'workflow_dispatch:' + } +}