| File: | blib/lib/App/GHGen/Generator.pm |
| Coverage: | 98.8% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package App::GHGen::Generator; | |||||
| 2 | ||||||
| 3 | 5 5 | 1073 9 | use v5.36; | |||
| 4 | ||||||
| 5 | 5 5 5 | 6 4 31 | use strict; | |||
| 6 | 5 5 5 | 6 2 83 | use warnings; | |||
| 7 | ||||||
| 8 | 5 5 5 | 676 5 120 | use App::GHGen::PerlCustomizer qw(detect_perl_requirements generate_custom_perl_workflow); | |||
| 9 | ||||||
| 10 | 5 5 5 | 8 3 1012 | use Exporter 'import'; | |||
| 11 | our @EXPORT_OK = qw( | |||||
| 12 | generate_workflow | |||||
| 13 | list_workflow_types | |||||
| 14 | ); | |||||
| 15 | ||||||
| 16 | our $VERSION = '0.10'; | |||||
| 17 | ||||||
| 18 - 88 | =head1 NAME
App::GHGen::Generator - Generate GitHub Actions workflows
=head1 SYNOPSIS
use App::GHGen::Generator qw(generate_workflow);
use Path::Tiny;
my $yaml = generate_workflow('perl');
path('.github/workflows/ci.yml')->spew_utf8($yaml);
=head1 FUNCTIONS
=head2 generate_workflow($type)
Generate a complete GitHub Actions workflow YAML string for the given project type.
=head3 Purpose
Dispatch to the appropriate language-specific workflow generator and return
the resulting YAML string ready to be written to a C<.github/workflows/> file.
=head3 Arguments
=over 4
=item C<$type> (Str, required)
A project-type identifier. Supported values: C<perl>, C<node>, C<python>,
C<rust>, C<go>, C<ruby>, C<java>, C<cpp>, C<php>, C<docker>, C<static>.
=back
=head3 Returns
A multi-line YAML string beginning with C<---> when C<$type> is recognised,
or C<undef> when the type is not supported.
=head3 Side Effects
The C<perl> type reads the current directory to detect project requirements
(via L<App::GHGen::PerlCustomizer>).
=head3 Usage Example
use App::GHGen::Generator qw(generate_workflow);
my $yaml = generate_workflow('node') // die "unsupported type";
path('.github/workflows/ci.yml')->spew_utf8($yaml);
=head3 API SPECIFICATION
=head4 Input
{ type => { type => 'scalar', required => 1 } }
=head4 Output
known type â { type => 'scalar' } # YAML string
unknown type â undef
=head3 FORMAL SPECIFICATION
SupportedTypes â { perl, node, python, rust, go, ruby, java, cpp, php, docker, static }
generate_workflow : â¤* â â¤* ⪠{ ⥠}
t â SupportedTypes â generators[t]() (non-empty YAML string)
t â SupportedTypes â ⥠(undef)
=cut | |||||
| 89 | ||||||
| 90 | 38 38 38 | 27156 28 34 | sub generate_workflow($type) { | |||
| 91 | 38 | 100 | my %generators = ( | |||
| 92 | perl => \&_generate_perl_workflow, | |||||
| 93 | node => \&_generate_node_workflow, | |||||
| 94 | python => \&_generate_python_workflow, | |||||
| 95 | rust => \&_generate_rust_workflow, | |||||
| 96 | go => \&_generate_go_workflow, | |||||
| 97 | ruby => \&_generate_ruby_workflow, | |||||
| 98 | java => \&_generate_java_workflow, | |||||
| 99 | cpp => \&_generate_cpp_workflow, | |||||
| 100 | php => \&_generate_php_workflow, | |||||
| 101 | docker => \&_generate_docker_workflow, | |||||
| 102 | static => \&_generate_static_workflow, | |||||
| 103 | ); | |||||
| 104 | ||||||
| 105 | 38 | 45 | return undef unless exists $generators{$type}; | |||
| 106 | 35 | 39 | return $generators{$type}->(); | |||
| 107 | } | |||||
| 108 | ||||||
| 109 - 154 | =head2 list_workflow_types()
Return a flat hash of all supported workflow types and their descriptions.
=head3 Purpose
Enumerate every type that C<generate_workflow> can handle, with a one-line
human-readable description for each.
=head3 Arguments
None.
=head3 Returns
A flat hash (not a reference) mapping type strings to description strings.
Contains exactly eleven entries: C<perl>, C<node>, C<python>, C<rust>,
C<go>, C<ruby>, C<java>, C<cpp>, C<php>, C<docker>, C<static>.
=head3 Side Effects
None. Pure function.
=head3 Usage Example
my %types = list_workflow_types();
say "$_: $types{$_}" for sort keys %types;
=head3 API SPECIFICATION
=head4 Input
# No parameters.
=head4 Output
{ type => 'hashref', keys => { '*' => { type => 'scalar' } } }
=head3 FORMAL SPECIFICATION
list_workflow_types : â â¤* â â¤*
result â { t ⦠desc(t) ⣠t â SupportedTypes }
|result| = 11
=cut | |||||
| 155 | ||||||
| 156 | 4 4 | 7799 4 | sub list_workflow_types() { | |||
| 157 | return ( | |||||
| 158 | 4 | 22 | node => 'Node.js/npm projects with testing and linting', | |||
| 159 | python => 'Python projects with pytest and coverage', | |||||
| 160 | rust => 'Rust projects with cargo, clippy, and formatting', | |||||
| 161 | go => 'Go projects with testing and race detection', | |||||
| 162 | ruby => 'Ruby projects with bundler and rake', | |||||
| 163 | perl => 'Perl projects with cpanm, prove, and coverage', | |||||
| 164 | java => 'Java projects with Maven or Gradle', | |||||
| 165 | cpp => 'C++ projects with CMake', | |||||
| 166 | php => 'PHP projects with Composer and PHPUnit', | |||||
| 167 | docker => 'Docker image build and push workflow', | |||||
| 168 | static => 'Static site deployment to GitHub Pages', | |||||
| 169 | ); | |||||
| 170 | } | |||||
| 171 | ||||||
| 172 | # Private workflow generators | |||||
| 173 | ||||||
| 174 | 5 5 | 1005 5 | sub _generate_perl_workflow() { | |||
| 175 | # Try to detect requirements from project | |||||
| 176 | 5 | 9 | my $reqs = detect_perl_requirements(); | |||
| 177 | ||||||
| 178 | # Use detected min version or default to 5.36 | |||||
| 179 | 5 | 11 | my $min_version = $reqs->{min_version} // '5.36'; | |||
| 180 | ||||||
| 181 | # Generate custom workflow with detected settings | |||||
| 182 | 5 | 22 | return generate_custom_perl_workflow({ | |||
| 183 | min_perl_version => $min_version, | |||||
| 184 | max_perl_version => '5.40', | |||||
| 185 | os => ['macos-latest', 'ubuntu-latest', 'windows-latest'], | |||||
| 186 | enable_critic => 1, | |||||
| 187 | enable_coverage => 1, | |||||
| 188 | }); | |||||
| 189 | } | |||||
| 190 | ||||||
| 191 | 4 4 | 3 2 | sub _generate_node_workflow() { | |||
| 192 | 4 | 8 | return <<'YAML'; | |||
| 193 | --- | |||||
| 194 | name: Node.js CI | |||||
| 195 | ||||||
| 196 | 'on': | |||||
| 197 | push: | |||||
| 198 | branches: | |||||
| 199 | - main | |||||
| 200 | - develop | |||||
| 201 | pull_request: | |||||
| 202 | branches: | |||||
| 203 | - main | |||||
| 204 | - develop | |||||
| 205 | ||||||
| 206 | concurrency: | |||||
| 207 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 208 | cancel-in-progress: true | |||||
| 209 | ||||||
| 210 | permissions: | |||||
| 211 | contents: read | |||||
| 212 | ||||||
| 213 | jobs: | |||||
| 214 | test: | |||||
| 215 | runs-on: ubuntu-latest | |||||
| 216 | strategy: | |||||
| 217 | matrix: | |||||
| 218 | node-version: | |||||
| 219 | - 18.x | |||||
| 220 | - 20.x | |||||
| 221 | - 22.x | |||||
| 222 | steps: | |||||
| 223 | - name: Checkout code | |||||
| 224 | uses: actions/checkout@76 | |||||
| 225 | ||||||
| 226 | - name: Setup Node.js ${{ matrix.node-version }} | |||||
| 227 | uses: actions/setup-node@v4 | |||||
| 228 | with: | |||||
| 229 | node-version: ${{ matrix.node-version }} | |||||
| 230 | ||||||
| 231 | - name: Cache dependencies | |||||
| 232 | uses: actions/cache@v6 | |||||
| 233 | with: | |||||
| 234 | path: ~/.npm | |||||
| 235 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |||||
| 236 | restore-keys: | | |||||
| 237 | ${{ runner.os }}-node- | |||||
| 238 | ||||||
| 239 | - name: Install dependencies | |||||
| 240 | run: npm ci | |||||
| 241 | ||||||
| 242 | - name: Run linter | |||||
| 243 | run: npm run lint --if-present | |||||
| 244 | ||||||
| 245 | - name: Run tests | |||||
| 246 | run: npm test | |||||
| 247 | ||||||
| 248 | - name: Build project | |||||
| 249 | run: npm run build --if-present | |||||
| 250 | YAML | |||||
| 251 | } | |||||
| 252 | ||||||
| 253 | 3 3 | 3 3 | sub _generate_python_workflow() { | |||
| 254 | 3 | 5 | return <<'YAML'; | |||
| 255 | --- | |||||
| 256 | name: Python CI | |||||
| 257 | ||||||
| 258 | 'on': | |||||
| 259 | push: | |||||
| 260 | branches: | |||||
| 261 | - main | |||||
| 262 | - develop | |||||
| 263 | pull_request: | |||||
| 264 | branches: | |||||
| 265 | - main | |||||
| 266 | - develop | |||||
| 267 | ||||||
| 268 | concurrency: | |||||
| 269 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 270 | cancel-in-progress: true | |||||
| 271 | ||||||
| 272 | permissions: | |||||
| 273 | contents: read | |||||
| 274 | ||||||
| 275 | jobs: | |||||
| 276 | test: | |||||
| 277 | runs-on: ubuntu-latest | |||||
| 278 | strategy: | |||||
| 279 | matrix: | |||||
| 280 | python-version: | |||||
| 281 | - '3.9' | |||||
| 282 | - '3.10' | |||||
| 283 | - '3.11' | |||||
| 284 | - '3.12' | |||||
| 285 | steps: | |||||
| 286 | - name: Checkout code | |||||
| 287 | uses: actions/checkout@v7 | |||||
| 288 | ||||||
| 289 | - name: Set up Python ${{ matrix.python-version }} | |||||
| 290 | uses: actions/setup-python@v5 | |||||
| 291 | with: | |||||
| 292 | python-version: ${{ matrix.python-version }} | |||||
| 293 | ||||||
| 294 | - name: Cache pip packages | |||||
| 295 | uses: actions/cache@v6 | |||||
| 296 | with: | |||||
| 297 | path: ~/.cache/pip | |||||
| 298 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} | |||||
| 299 | restore-keys: | | |||||
| 300 | ${{ runner.os }}-pip- | |||||
| 301 | ||||||
| 302 | - name: Install dependencies | |||||
| 303 | run: | | |||||
| 304 | pip install -r requirements.txt | |||||
| 305 | pip install pytest pytest-cov flake8 | |||||
| 306 | ||||||
| 307 | - name: Lint with flake8 | |||||
| 308 | run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics | |||||
| 309 | ||||||
| 310 | - name: Run tests with coverage | |||||
| 311 | run: pytest --cov=. --cov-report=xml | |||||
| 312 | YAML | |||||
| 313 | } | |||||
| 314 | ||||||
| 315 | 3 3 | 2 3 | sub _generate_rust_workflow() { | |||
| 316 | 3 | 5 | return <<'YAML'; | |||
| 317 | --- | |||||
| 318 | name: Rust CI | |||||
| 319 | ||||||
| 320 | 'on': | |||||
| 321 | push: | |||||
| 322 | branches: | |||||
| 323 | - main | |||||
| 324 | pull_request: | |||||
| 325 | branches: | |||||
| 326 | - main | |||||
| 327 | ||||||
| 328 | concurrency: | |||||
| 329 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 330 | cancel-in-progress: true | |||||
| 331 | ||||||
| 332 | permissions: | |||||
| 333 | contents: read | |||||
| 334 | ||||||
| 335 | jobs: | |||||
| 336 | test: | |||||
| 337 | runs-on: ubuntu-latest | |||||
| 338 | steps: | |||||
| 339 | - name: Checkout code | |||||
| 340 | uses: actions/checkout@v7 | |||||
| 341 | ||||||
| 342 | - name: Setup Rust | |||||
| 343 | uses: dtolnay/rust-toolchain@stable | |||||
| 344 | ||||||
| 345 | - name: Cache cargo | |||||
| 346 | uses: actions/cache@v6 | |||||
| 347 | with: | |||||
| 348 | path: | | |||||
| 349 | ~/.cargo/bin/ | |||||
| 350 | ~/.cargo/registry/index/ | |||||
| 351 | ~/.cargo/registry/cache/ | |||||
| 352 | ~/.cargo/git/db/ | |||||
| 353 | target/ | |||||
| 354 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |||||
| 355 | ||||||
| 356 | - name: Check formatting | |||||
| 357 | run: cargo fmt -- --check | |||||
| 358 | ||||||
| 359 | - name: Run clippy | |||||
| 360 | run: cargo clippy -- -D warnings | |||||
| 361 | ||||||
| 362 | - name: Run tests | |||||
| 363 | run: cargo test --verbose | |||||
| 364 | ||||||
| 365 | - name: Build release | |||||
| 366 | run: cargo build --release --verbose | |||||
| 367 | YAML | |||||
| 368 | } | |||||
| 369 | ||||||
| 370 | 3 3 | 2 2 | sub _generate_go_workflow() { | |||
| 371 | 3 | 6 | return <<'YAML'; | |||
| 372 | --- | |||||
| 373 | name: Go CI | |||||
| 374 | ||||||
| 375 | 'on': | |||||
| 376 | push: | |||||
| 377 | branches: | |||||
| 378 | - main | |||||
| 379 | pull_request: | |||||
| 380 | branches: | |||||
| 381 | - main | |||||
| 382 | ||||||
| 383 | concurrency: | |||||
| 384 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 385 | cancel-in-progress: true | |||||
| 386 | ||||||
| 387 | permissions: | |||||
| 388 | contents: read | |||||
| 389 | ||||||
| 390 | jobs: | |||||
| 391 | test: | |||||
| 392 | runs-on: ubuntu-latest | |||||
| 393 | steps: | |||||
| 394 | - name: Checkout code | |||||
| 395 | uses: actions/checkout@v7 | |||||
| 396 | ||||||
| 397 | - name: Setup Go | |||||
| 398 | uses: actions/setup-go@v5 | |||||
| 399 | with: | |||||
| 400 | go-version: '1.22' | |||||
| 401 | ||||||
| 402 | - name: Cache Go modules | |||||
| 403 | uses: actions/cache@v6 | |||||
| 404 | with: | |||||
| 405 | path: ~/go/pkg/mod | |||||
| 406 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |||||
| 407 | restore-keys: | | |||||
| 408 | ${{ runner.os }}-go- | |||||
| 409 | ||||||
| 410 | - name: Download dependencies | |||||
| 411 | run: go mod download | |||||
| 412 | ||||||
| 413 | - name: Run go vet | |||||
| 414 | run: go vet ./... | |||||
| 415 | ||||||
| 416 | - name: Run tests | |||||
| 417 | run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... | |||||
| 418 | ||||||
| 419 | - name: Build | |||||
| 420 | run: go build -v ./... | |||||
| 421 | YAML | |||||
| 422 | } | |||||
| 423 | ||||||
| 424 | 3 3 | 3 1 | sub _generate_ruby_workflow() { | |||
| 425 | 3 | 6 | return <<'YAML'; | |||
| 426 | --- | |||||
| 427 | name: Ruby CI | |||||
| 428 | ||||||
| 429 | 'on': | |||||
| 430 | push: | |||||
| 431 | branches: | |||||
| 432 | - main | |||||
| 433 | pull_request: | |||||
| 434 | branches: | |||||
| 435 | - main | |||||
| 436 | ||||||
| 437 | concurrency: | |||||
| 438 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 439 | cancel-in-progress: true | |||||
| 440 | ||||||
| 441 | permissions: | |||||
| 442 | contents: read | |||||
| 443 | ||||||
| 444 | jobs: | |||||
| 445 | test: | |||||
| 446 | runs-on: ubuntu-latest | |||||
| 447 | strategy: | |||||
| 448 | matrix: | |||||
| 449 | ruby-version: | |||||
| 450 | - '3.1' | |||||
| 451 | - '3.2' | |||||
| 452 | - '3.3' | |||||
| 453 | steps: | |||||
| 454 | - name: Checkout code | |||||
| 455 | uses: actions/checkout@v7 | |||||
| 456 | ||||||
| 457 | - name: Set up Ruby | |||||
| 458 | uses: ruby/setup-ruby@v1 | |||||
| 459 | with: | |||||
| 460 | ruby-version: ${{ matrix.ruby-version }} | |||||
| 461 | bundler-cache: true | |||||
| 462 | ||||||
| 463 | - name: Run tests | |||||
| 464 | run: bundle exec rake test | |||||
| 465 | YAML | |||||
| 466 | } | |||||
| 467 | ||||||
| 468 | 3 3 | 3 1 | sub _generate_docker_workflow() { | |||
| 469 | 3 | 6 | return <<'YAML'; | |||
| 470 | --- | |||||
| 471 | name: Docker Build | |||||
| 472 | ||||||
| 473 | 'on': | |||||
| 474 | push: | |||||
| 475 | branches: | |||||
| 476 | - main | |||||
| 477 | tags: | |||||
| 478 | - v* | |||||
| 479 | pull_request: | |||||
| 480 | branches: | |||||
| 481 | - main | |||||
| 482 | ||||||
| 483 | concurrency: | |||||
| 484 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 485 | cancel-in-progress: true | |||||
| 486 | ||||||
| 487 | permissions: | |||||
| 488 | contents: read | |||||
| 489 | packages: write | |||||
| 490 | ||||||
| 491 | jobs: | |||||
| 492 | build: | |||||
| 493 | runs-on: ubuntu-latest | |||||
| 494 | steps: | |||||
| 495 | - name: Checkout code | |||||
| 496 | uses: actions/checkout@v7 | |||||
| 497 | ||||||
| 498 | - name: Set up Docker Buildx | |||||
| 499 | uses: docker/setup-buildx-action@v3 | |||||
| 500 | ||||||
| 501 | - name: Log in to Docker Hub | |||||
| 502 | uses: docker/login-action@v3 | |||||
| 503 | with: | |||||
| 504 | username: ${{ secrets.DOCKER_USERNAME }} | |||||
| 505 | password: ${{ secrets.DOCKER_PASSWORD }} | |||||
| 506 | if: github.event_name != 'pull_request' | |||||
| 507 | ||||||
| 508 | - name: Extract metadata | |||||
| 509 | id: meta | |||||
| 510 | uses: docker/metadata-action@v5 | |||||
| 511 | with: | |||||
| 512 | images: your-username/your-image | |||||
| 513 | ||||||
| 514 | - name: Build and push | |||||
| 515 | uses: docker/build-push-action@v5 | |||||
| 516 | with: | |||||
| 517 | context: . | |||||
| 518 | push: ${{ github.event_name != 'pull_request' }} | |||||
| 519 | tags: ${{ steps.meta.outputs.tags }} | |||||
| 520 | labels: ${{ steps.meta.outputs.labels }} | |||||
| 521 | cache-from: type=gha | |||||
| 522 | cache-to: type=gha,mode=max | |||||
| 523 | YAML | |||||
| 524 | } | |||||
| 525 | ||||||
| 526 | 3 3 | 1 3 | sub _generate_static_workflow() { | |||
| 527 | 3 | 5 | return <<'YAML'; | |||
| 528 | --- | |||||
| 529 | name: Deploy Static Site | |||||
| 530 | ||||||
| 531 | 'on': | |||||
| 532 | push: | |||||
| 533 | branches: | |||||
| 534 | - main | |||||
| 535 | ||||||
| 536 | permissions: | |||||
| 537 | contents: read | |||||
| 538 | pages: write | |||||
| 539 | id-token: write | |||||
| 540 | ||||||
| 541 | concurrency: | |||||
| 542 | group: pages | |||||
| 543 | cancel-in-progress: false | |||||
| 544 | ||||||
| 545 | jobs: | |||||
| 546 | build: | |||||
| 547 | runs-on: ubuntu-latest | |||||
| 548 | steps: | |||||
| 549 | - name: Checkout | |||||
| 550 | uses: actions/checkout@v7 | |||||
| 551 | ||||||
| 552 | - name: Setup Pages | |||||
| 553 | uses: actions/configure-pages@v4 | |||||
| 554 | ||||||
| 555 | - name: Build | |||||
| 556 | run: echo "Add your build command here" | |||||
| 557 | ||||||
| 558 | - name: Upload artifact | |||||
| 559 | uses: actions/upload-pages-artifact@v3 | |||||
| 560 | with: | |||||
| 561 | path: ./public | |||||
| 562 | ||||||
| 563 | deploy: | |||||
| 564 | environment: | |||||
| 565 | name: github-pages | |||||
| 566 | url: ${{ steps.deployment.outputs.page_url }} | |||||
| 567 | runs-on: ubuntu-latest | |||||
| 568 | needs: build | |||||
| 569 | steps: | |||||
| 570 | - name: Deploy to GitHub Pages | |||||
| 571 | id: deployment | |||||
| 572 | uses: actions/deploy-pages@v4 | |||||
| 573 | YAML | |||||
| 574 | } | |||||
| 575 | ||||||
| 576 | 3 3 | 3 2 | sub _generate_java_workflow() { | |||
| 577 | 3 | 4 | return <<'YAML'; | |||
| 578 | --- | |||||
| 579 | name: Java CI | |||||
| 580 | ||||||
| 581 | 'on': | |||||
| 582 | push: | |||||
| 583 | branches: | |||||
| 584 | - main | |||||
| 585 | - develop | |||||
| 586 | pull_request: | |||||
| 587 | branches: | |||||
| 588 | - main | |||||
| 589 | - develop | |||||
| 590 | ||||||
| 591 | concurrency: | |||||
| 592 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 593 | cancel-in-progress: true | |||||
| 594 | ||||||
| 595 | permissions: | |||||
| 596 | contents: read | |||||
| 597 | ||||||
| 598 | jobs: | |||||
| 599 | test: | |||||
| 600 | runs-on: ubuntu-latest | |||||
| 601 | strategy: | |||||
| 602 | matrix: | |||||
| 603 | java-version: | |||||
| 604 | - '11' | |||||
| 605 | - '17' | |||||
| 606 | - '21' | |||||
| 607 | steps: | |||||
| 608 | - name: Checkout code | |||||
| 609 | uses: actions/checkout@v7 | |||||
| 610 | ||||||
| 611 | - name: Set up JDK ${{ matrix.java-version }} | |||||
| 612 | uses: actions/setup-java@v4 | |||||
| 613 | with: | |||||
| 614 | java-version: ${{ matrix.java-version }} | |||||
| 615 | distribution: 'temurin' | |||||
| 616 | ||||||
| 617 | - name: Cache Maven packages | |||||
| 618 | uses: actions/cache@v6 | |||||
| 619 | with: | |||||
| 620 | path: ~/.m2/repository | |||||
| 621 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} | |||||
| 622 | restore-keys: | | |||||
| 623 | ${{ runner.os }}-maven- | |||||
| 624 | ||||||
| 625 | - name: Build with Maven | |||||
| 626 | run: mvn -B package --file pom.xml | |||||
| 627 | ||||||
| 628 | - name: Run tests | |||||
| 629 | run: mvn -B test | |||||
| 630 | ||||||
| 631 | - name: Generate test report | |||||
| 632 | if: always() | |||||
| 633 | run: mvn surefire-report:report | |||||
| 634 | YAML | |||||
| 635 | } | |||||
| 636 | ||||||
| 637 | 3 3 | 3 31 | sub _generate_cpp_workflow() { | |||
| 638 | 3 | 6 | return <<'YAML'; | |||
| 639 | --- | |||||
| 640 | name: C++ CI | |||||
| 641 | ||||||
| 642 | 'on': | |||||
| 643 | push: | |||||
| 644 | branches: | |||||
| 645 | - main | |||||
| 646 | pull_request: | |||||
| 647 | branches: | |||||
| 648 | - main | |||||
| 649 | ||||||
| 650 | concurrency: | |||||
| 651 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 652 | cancel-in-progress: true | |||||
| 653 | ||||||
| 654 | permissions: | |||||
| 655 | contents: read | |||||
| 656 | ||||||
| 657 | jobs: | |||||
| 658 | test: | |||||
| 659 | runs-on: ${{ matrix.os }} | |||||
| 660 | strategy: | |||||
| 661 | matrix: | |||||
| 662 | os: | |||||
| 663 | - ubuntu-latest | |||||
| 664 | - macos-latest | |||||
| 665 | - windows-latest | |||||
| 666 | build-type: | |||||
| 667 | - Debug | |||||
| 668 | - Release | |||||
| 669 | steps: | |||||
| 670 | - name: Checkout code | |||||
| 671 | uses: actions/checkout@v7 | |||||
| 672 | ||||||
| 673 | - name: Install CMake | |||||
| 674 | uses: lukka/get-cmake@latest | |||||
| 675 | ||||||
| 676 | - name: Cache build artifacts | |||||
| 677 | uses: actions/cache@v6 | |||||
| 678 | with: | |||||
| 679 | path: | | |||||
| 680 | build | |||||
| 681 | ~/.cache/ccache | |||||
| 682 | key: ${{ runner.os }}-${{ matrix.build-type }}-${{ hashFiles('**/CMakeLists.txt') }} | |||||
| 683 | ||||||
| 684 | - name: Configure CMake | |||||
| 685 | run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} | |||||
| 686 | ||||||
| 687 | - name: Build | |||||
| 688 | run: cmake --build build --config ${{ matrix.build-type }} | |||||
| 689 | ||||||
| 690 | - name: Run tests | |||||
| 691 | working-directory: build | |||||
| 692 | run: ctest -C ${{ matrix.build-type }} --output-on-failure | |||||
| 693 | YAML | |||||
| 694 | } | |||||
| 695 | ||||||
| 696 | 3 3 | 3 2 | sub _generate_php_workflow() { | |||
| 697 | 3 | 5 | return <<'YAML'; | |||
| 698 | --- | |||||
| 699 | name: PHP CI | |||||
| 700 | ||||||
| 701 | 'on': | |||||
| 702 | push: | |||||
| 703 | branches: | |||||
| 704 | - main | |||||
| 705 | - develop | |||||
| 706 | pull_request: | |||||
| 707 | branches: | |||||
| 708 | - main | |||||
| 709 | - develop | |||||
| 710 | ||||||
| 711 | concurrency: | |||||
| 712 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 713 | cancel-in-progress: true | |||||
| 714 | ||||||
| 715 | permissions: | |||||
| 716 | contents: read | |||||
| 717 | ||||||
| 718 | jobs: | |||||
| 719 | test: | |||||
| 720 | runs-on: ubuntu-latest | |||||
| 721 | strategy: | |||||
| 722 | matrix: | |||||
| 723 | php-version: | |||||
| 724 | - '8.1' | |||||
| 725 | - '8.2' | |||||
| 726 | - '8.3' | |||||
| 727 | steps: | |||||
| 728 | - name: Checkout code | |||||
| 729 | uses: actions/checkout@v7 | |||||
| 730 | ||||||
| 731 | - name: Setup PHP ${{ matrix.php-version }} | |||||
| 732 | uses: shivammathur/setup-php@v2 | |||||
| 733 | with: | |||||
| 734 | php-version: ${{ matrix.php-version }} | |||||
| 735 | extensions: mbstring, xml, ctype, json | |||||
| 736 | coverage: xdebug | |||||
| 737 | ||||||
| 738 | - name: Validate composer.json | |||||
| 739 | run: composer validate --strict | |||||
| 740 | ||||||
| 741 | - name: Cache Composer packages | |||||
| 742 | uses: actions/cache@v6 | |||||
| 743 | with: | |||||
| 744 | path: vendor | |||||
| 745 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} | |||||
| 746 | restore-keys: | | |||||
| 747 | ${{ runner.os }}-php- | |||||
| 748 | ||||||
| 749 | - name: Install dependencies | |||||
| 750 | run: composer install --prefer-dist --no-progress | |||||
| 751 | ||||||
| 752 | - name: Run PHPUnit tests | |||||
| 753 | run: vendor/bin/phpunit --coverage-text | |||||
| 754 | ||||||
| 755 | - name: Run PHP CodeSniffer | |||||
| 756 | run: vendor/bin/phpcs --standard=PSR12 src tests | |||||
| 757 | continue-on-error: true | |||||
| 758 | YAML | |||||
| 759 | } | |||||
| 760 | ||||||
| 761 - 772 | =head1 AUTHOR Nigel Horne E<lt>njh@nigelhorne.comE<gt> L<https://github.com/nigelhorne> =head1 LICENSE This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut | |||||
| 773 | ||||||
| 774 | 1; | |||||