mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-16 16:45:07 +00:00
7045da7450
c05927c1added a `concurrency:` block on the premise that the suite never got one. It already had one, four lines above -- the hunk header of that diff reads `@@ -50,6 +50,23 @@ concurrency:`, which is the existing block it was appended below. A YAML mapping cannot carry the same key twice, so the file has not loaded since. GitHub still creates a run and then schedules nothing:553f5fd2(last green) run 33036453748 jobs=1 ci -> successd58e4830(main) run 33114046849 jobs=0 failure Every run since has that shape, and the run list names it in passing: those runs appear as `.github/workflows/tests.yml` where the green ones appear as `tests`, because the `name:` key sits inside the file that did not parse. `linter` is unaffected -- it carries one block -- which is why351da21eshows a green linter beside a failed tests run, and the tree reads as half-checked rather than unchecked. Reproduced with a parser rather than inferred from the job count: before -> THREW: Duplicate key "concurrency" detected at line 66. after -> parsed ok, top-level keys: name,on,concurrency,jobs Kept the second block, verbatim, because it is the onec05927c1meant to end up with and its comment carries the reasoning -- including the tradeoff that an intermediate commit on `main` can end up with no run of its own. The two group keys are interchangeable: `github.workflow` is constant within a workflow, so `tests-${{ github.workflow }}-${{ github.ref }}` and `tests-${{ github.ref }}` produce the same grouping. Worth knowing that lint.yml still uses the first shape, if you would rather the two files read alike. No test. The failure is loud on the next push, and a test that parses a workflow file would be a second place to keep the same rule.
155 lines
5.6 KiB
YAML
155 lines
5.6 KiB
YAML
name: tests
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- develop
|
|
- main
|
|
paths-ignore:
|
|
# Files no code reads and no test covers. Deliberately NOT listed:
|
|
# CHANGELOG.md, which ReleaseNotes parses and ReleaseNotesTest
|
|
# covers, and docs/, whose only two tracked files are served by
|
|
# ApiDocsController and OpenApiController. A malformed edit to
|
|
# either is exactly the thing that must not skip the suite.
|
|
#
|
|
# Repeated verbatim under pull_request: GitHub Actions does not
|
|
# support YAML anchors.
|
|
- 'README.md'
|
|
- 'CONTRIBUTING.md'
|
|
- 'SECURITY.md'
|
|
- 'LICENSING.md'
|
|
- 'CLA-ENTITY.md'
|
|
- 'CLA-INDIVIDUAL.md'
|
|
- 'INSTALL.md'
|
|
- 'UPDATE.md'
|
|
- 'DOCKER.md'
|
|
- 'MIGRATING-FROM-V1.md'
|
|
- 'docker/production/dockerhub-overview.md'
|
|
- '.github/screenshots/**'
|
|
pull_request:
|
|
branches:
|
|
- develop
|
|
- main
|
|
paths-ignore:
|
|
- 'README.md'
|
|
- 'CONTRIBUTING.md'
|
|
- 'SECURITY.md'
|
|
- 'LICENSING.md'
|
|
- 'CLA-ENTITY.md'
|
|
- 'CLA-INDIVIDUAL.md'
|
|
- 'INSTALL.md'
|
|
- 'UPDATE.md'
|
|
- 'DOCKER.md'
|
|
- 'MIGRATING-FROM-V1.md'
|
|
- 'docker/production/dockerhub-overview.md'
|
|
- '.github/screenshots/**'
|
|
|
|
# A second push supersedes the first — the later run covers a superset of
|
|
# what the earlier one was checking, so finishing both buys nothing and
|
|
# costs a runner.
|
|
#
|
|
# Keyed on the ref, so `main` and a branch never cancel each other. A push
|
|
# to a branch that also has a pull request open produces two events with
|
|
# two different refs, which is why they do not fight either.
|
|
#
|
|
# The tradeoff worth naming: on `main` this means an intermediate commit
|
|
# can end up with no run of its own when two pushes land together. That is
|
|
# accepted here — what is being verified is the state of the branch, and
|
|
# the run that survives is the one that includes both commits. If a commit
|
|
# ever needs its own green tick (a bisect, a release audit), push it alone.
|
|
concurrency:
|
|
group: tests-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
ci:
|
|
runs-on: ubuntu-latest
|
|
|
|
# This job has no MySQL/db service — it's SQLite-only (see
|
|
# phpunit.xml) — but .env.example's DB_CONNECTION=mysql/DB_HOST=db is
|
|
# for the local docker-compose stack. Bare artisan calls that run
|
|
# outside phpunit.xml's env (composer's package:discover,
|
|
# key:generate) would otherwise try to reach a "db" host that
|
|
# doesn't exist here. Same story for CACHE_STORE: every process
|
|
# boot reads a mail-config cache entry (PlatformServiceProvider::
|
|
# boot() -> MailConfigApplier::apply()), which needs a store that
|
|
# works without a migrated schema this early.
|
|
env:
|
|
CACHE_STORE: array
|
|
DB_CONNECTION: sqlite
|
|
# config/database.php's sqlite connection reuses DB_DATABASE for
|
|
# the file path — .env.example's DB_DATABASE=projectsend (the
|
|
# MySQL database name) would otherwise make sqlite look for a
|
|
# file literally named "projectsend".
|
|
DB_DATABASE: database/database.sqlite
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup PHP
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: 8.4
|
|
tools: composer:v2
|
|
coverage: xdebug
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
cache: 'npm'
|
|
|
|
# community-modules is the community edition's companion package,
|
|
# resolved from its public GitHub repository (the vcs entry in
|
|
# composer.json). A plain clone installs it with no local packages/
|
|
# checkout — cloud-modules is not required at all. COMPOSER_AUTH just
|
|
# hands composer the runner's token so the GitHub API calls it makes
|
|
# to fetch the package are not subject to the anonymous rate limit.
|
|
|
|
# composer install's post-autoload-dump script boots the app
|
|
# (package:discover), which needs the sqlite file to already exist
|
|
# even before .env is copied — config/database.php defaults to it.
|
|
- name: Create SQLite Database
|
|
run: touch database/database.sqlite
|
|
|
|
- name: Install PHP Dependencies
|
|
env:
|
|
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GITHUB_TOKEN }}"}}'
|
|
run: composer install --no-interaction --prefer-dist --optimize-autoloader
|
|
|
|
- name: Install Node Dependencies
|
|
run: npm ci
|
|
|
|
# tsconfig.json maps the "ziggy-js" import to vendor/tightenco/ziggy,
|
|
# so this needs PHP deps installed first.
|
|
- name: Typecheck Frontend
|
|
run: npm run types
|
|
|
|
- name: Build Assets
|
|
run: npm run build
|
|
|
|
- name: Copy Environment File
|
|
run: cp .env.example .env
|
|
|
|
- name: Generate Application Key
|
|
run: php artisan key:generate
|
|
|
|
- name: Static Analysis
|
|
run: ./vendor/bin/phpstan analyse --no-progress
|
|
|
|
# `--parallel` rather than a shorter suite. One process took 191s of
|
|
# this job's 4m30s; the same 1763 tests across the runner's cores
|
|
# take about a third of that, with nothing skipped. paratest is
|
|
# already a dev dependency (via Pest), so this needs no new install.
|
|
#
|
|
# `:memory:` explicitly: parallel testing gives each process its own
|
|
# database, and an in-memory one per process is what the suite is
|
|
# verified against locally. The job-level DB_DATABASE above is a file
|
|
# path, which parallel workers would have to create and migrate
|
|
# individually — a difference in behaviour with nothing to gain.
|
|
- name: Tests
|
|
run: ./vendor/bin/pest --parallel
|
|
env:
|
|
DB_DATABASE: ':memory:'
|