| File: | blib/lib/App/GHGen/Generator.pm |
| Coverage: | 47.8% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package App::GHGen::Generator; | |||||
| 2 | ||||||
| 3 | 1 1 | 485 2 | use v5.36; | |||
| 4 | ||||||
| 5 | 1 1 1 | 1 1 7 | use strict; | |||
| 6 | 1 1 1 | 1 0 15 | use warnings; | |||
| 7 | ||||||
| 8 | 1 1 1 | 389 5104 32 | use Path::Tiny; | |||
| 9 | 1 1 1 | 165 2 32 | use App::GHGen::PerlCustomizer qw(detect_perl_requirements generate_custom_perl_workflow); | |||
| 10 | ||||||
| 11 | 1 1 1 | 2 1 229 | use Exporter 'import'; | |||
| 12 | our @EXPORT_OK = qw( | |||||
| 13 | generate_workflow | |||||
| 14 | list_workflow_types | |||||
| 15 | get_workflow_description | |||||
| 16 | ); | |||||
| 17 | ||||||
| 18 | our $VERSION = '0.03'; | |||||
| 19 | ||||||
| 20 - 37 | =head1 NAME
App::GHGen::Generator - Generate GitHub Actions workflows
=head1 SYNOPSIS
use App::GHGen::Generator qw(generate_workflow);
my $yaml = generate_workflow('perl');
path('.github/workflows/ci.yml')->spew_utf8($yaml);
=head1 FUNCTIONS
=head2 generate_workflow($type)
Generate a workflow for the specified type. Returns YAML as a string.
=cut | |||||
| 38 | ||||||
| 39 | 2 2 2 | 421 3 0 | sub generate_workflow($type) { | |||
| 40 | 2 | 8 | my %generators = ( | |||
| 41 | perl => \&_generate_perl_workflow, | |||||
| 42 | node => \&_generate_node_workflow, | |||||
| 43 | python => \&_generate_python_workflow, | |||||
| 44 | rust => \&_generate_rust_workflow, | |||||
| 45 | go => \&_generate_go_workflow, | |||||
| 46 | ruby => \&_generate_ruby_workflow, | |||||
| 47 | java => \&_generate_java_workflow, | |||||
| 48 | cpp => \&_generate_cpp_workflow, | |||||
| 49 | php => \&_generate_php_workflow, | |||||
| 50 | docker => \&_generate_docker_workflow, | |||||
| 51 | static => \&_generate_static_workflow, | |||||
| 52 | ); | |||||
| 53 | ||||||
| 54 | 2 | 4 | return undef unless exists $generators{$type}; | |||
| 55 | 1 | 1 | return $generators{$type}->(); | |||
| 56 | } | |||||
| 57 | ||||||
| 58 - 62 | =head2 list_workflow_types() Returns a hash of available workflow types and their descriptions. =cut | |||||
| 63 | ||||||
| 64 | 1 1 | 851 1 | sub list_workflow_types() { | |||
| 65 | return ( | |||||
| 66 | 1 | 3 | node => 'Node.js/npm projects with testing and linting', | |||
| 67 | python => 'Python projects with pytest and coverage', | |||||
| 68 | rust => 'Rust projects with cargo, clippy, and formatting', | |||||
| 69 | go => 'Go projects with testing and race detection', | |||||
| 70 | ruby => 'Ruby projects with bundler and rake', | |||||
| 71 | perl => 'Perl projects with cpanm, prove, and coverage', | |||||
| 72 | java => 'Java projects with Maven or Gradle', | |||||
| 73 | cpp => 'C++ projects with CMake', | |||||
| 74 | php => 'PHP projects with Composer and PHPUnit', | |||||
| 75 | docker => 'Docker image build and push workflow', | |||||
| 76 | static => 'Static site deployment to GitHub Pages', | |||||
| 77 | ); | |||||
| 78 | } | |||||
| 79 | ||||||
| 80 - 84 | =head2 get_workflow_description($type) Get the description for a specific workflow type. =cut | |||||
| 85 | ||||||
| 86 | 0 0 0 | 0 0 0 | sub get_workflow_description($type) { | |||
| 87 | 0 | 0 | my %types = list_workflow_types(); | |||
| 88 | 0 | 0 | return $types{$type}; | |||
| 89 | } | |||||
| 90 | ||||||
| 91 | # Private workflow generators | |||||
| 92 | ||||||
| 93 | 1 1 | 1 1 | sub _generate_perl_workflow() { | |||
| 94 | # Try to detect requirements from project | |||||
| 95 | 1 | 1 | my $reqs = detect_perl_requirements(); | |||
| 96 | ||||||
| 97 | # Use detected min version or default to 5.36 | |||||
| 98 | 1 | 2 | my $min_version = $reqs->{min_version} // '5.36'; | |||
| 99 | ||||||
| 100 | # Generate custom workflow with detected settings | |||||
| 101 | 1 | 22 | return generate_custom_perl_workflow({ | |||
| 102 | min_perl_version => $min_version, | |||||
| 103 | max_perl_version => '5.40', | |||||
| 104 | os => ['macos-latest', 'ubuntu-latest', 'windows-latest'], | |||||
| 105 | enable_critic => 1, | |||||
| 106 | enable_coverage => 1, | |||||
| 107 | }); | |||||
| 108 | } | |||||
| 109 | ||||||
| 110 | 0 0 | sub _generate_node_workflow() { | ||||
| 111 | 0 | return <<'YAML'; | ||||
| 112 | --- | |||||
| 113 | name: Node.js CI | |||||
| 114 | ||||||
| 115 | 'on': | |||||
| 116 | push: | |||||
| 117 | branches: | |||||
| 118 | - main | |||||
| 119 | - develop | |||||
| 120 | pull_request: | |||||
| 121 | branches: | |||||
| 122 | - main | |||||
| 123 | - develop | |||||
| 124 | ||||||
| 125 | concurrency: | |||||
| 126 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 127 | cancel-in-progress: true | |||||
| 128 | ||||||
| 129 | permissions: | |||||
| 130 | contents: read | |||||
| 131 | ||||||
| 132 | jobs: | |||||
| 133 | test: | |||||
| 134 | runs-on: ubuntu-latest | |||||
| 135 | strategy: | |||||
| 136 | matrix: | |||||
| 137 | node-version: | |||||
| 138 | - 18.x | |||||
| 139 | - 20.x | |||||
| 140 | - 22.x | |||||
| 141 | steps: | |||||
| 142 | - name: Checkout code | |||||
| 143 | uses: actions/checkout@v6 | |||||
| 144 | ||||||
| 145 | - name: Setup Node.js ${{ matrix.node-version }} | |||||
| 146 | uses: actions/setup-node@v4 | |||||
| 147 | with: | |||||
| 148 | node-version: ${{ matrix.node-version }} | |||||
| 149 | ||||||
| 150 | - name: Cache dependencies | |||||
| 151 | uses: actions/cache@v5 | |||||
| 152 | with: | |||||
| 153 | path: ~/.npm | |||||
| 154 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |||||
| 155 | restore-keys: | | |||||
| 156 | ${{ runner.os }}-node- | |||||
| 157 | ||||||
| 158 | - name: Install dependencies | |||||
| 159 | run: npm ci | |||||
| 160 | ||||||
| 161 | - name: Run linter | |||||
| 162 | run: npm run lint --if-present | |||||
| 163 | ||||||
| 164 | - name: Run tests | |||||
| 165 | run: npm test | |||||
| 166 | ||||||
| 167 | - name: Build project | |||||
| 168 | run: npm run build --if-present | |||||
| 169 | YAML | |||||
| 170 | } | |||||
| 171 | ||||||
| 172 | 0 0 | sub _generate_python_workflow() { | ||||
| 173 | 0 | return <<'YAML'; | ||||
| 174 | --- | |||||
| 175 | name: Python CI | |||||
| 176 | ||||||
| 177 | 'on': | |||||
| 178 | push: | |||||
| 179 | branches: | |||||
| 180 | - main | |||||
| 181 | - develop | |||||
| 182 | pull_request: | |||||
| 183 | branches: | |||||
| 184 | - main | |||||
| 185 | - develop | |||||
| 186 | ||||||
| 187 | concurrency: | |||||
| 188 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 189 | cancel-in-progress: true | |||||
| 190 | ||||||
| 191 | permissions: | |||||
| 192 | contents: read | |||||
| 193 | ||||||
| 194 | jobs: | |||||
| 195 | test: | |||||
| 196 | runs-on: ubuntu-latest | |||||
| 197 | strategy: | |||||
| 198 | matrix: | |||||
| 199 | python-version: | |||||
| 200 | - '3.9' | |||||
| 201 | - '3.10' | |||||
| 202 | - '3.11' | |||||
| 203 | - '3.12' | |||||
| 204 | steps: | |||||
| 205 | - name: Checkout code | |||||
| 206 | uses: actions/checkout@v6 | |||||
| 207 | ||||||
| 208 | - name: Set up Python ${{ matrix.python-version }} | |||||
| 209 | uses: actions/setup-python@v5 | |||||
| 210 | with: | |||||
| 211 | python-version: ${{ matrix.python-version }} | |||||
| 212 | ||||||
| 213 | - name: Cache pip packages | |||||
| 214 | uses: actions/cache@v5 | |||||
| 215 | with: | |||||
| 216 | path: ~/.cache/pip | |||||
| 217 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} | |||||
| 218 | restore-keys: | | |||||
| 219 | ${{ runner.os }}-pip- | |||||
| 220 | ||||||
| 221 | - name: Install dependencies | |||||
| 222 | run: | | |||||
| 223 | pip install -r requirements.txt | |||||
| 224 | pip install pytest pytest-cov flake8 | |||||
| 225 | ||||||
| 226 | - name: Lint with flake8 | |||||
| 227 | run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics | |||||
| 228 | ||||||
| 229 | - name: Run tests with coverage | |||||
| 230 | run: pytest --cov=. --cov-report=xml | |||||
| 231 | YAML | |||||
| 232 | } | |||||
| 233 | ||||||
| 234 | 0 0 | sub _generate_rust_workflow() { | ||||
| 235 | 0 | return <<'YAML'; | ||||
| 236 | --- | |||||
| 237 | name: Rust CI | |||||
| 238 | ||||||
| 239 | 'on': | |||||
| 240 | push: | |||||
| 241 | branches: | |||||
| 242 | - main | |||||
| 243 | pull_request: | |||||
| 244 | branches: | |||||
| 245 | - main | |||||
| 246 | ||||||
| 247 | concurrency: | |||||
| 248 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 249 | cancel-in-progress: true | |||||
| 250 | ||||||
| 251 | permissions: | |||||
| 252 | contents: read | |||||
| 253 | ||||||
| 254 | jobs: | |||||
| 255 | test: | |||||
| 256 | runs-on: ubuntu-latest | |||||
| 257 | steps: | |||||
| 258 | - name: Checkout code | |||||
| 259 | uses: actions/checkout@v6 | |||||
| 260 | ||||||
| 261 | - name: Setup Rust | |||||
| 262 | uses: dtolnay/rust-toolchain@stable | |||||
| 263 | ||||||
| 264 | - name: Cache cargo | |||||
| 265 | uses: actions/cache@v5 | |||||
| 266 | with: | |||||
| 267 | path: | | |||||
| 268 | ~/.cargo/bin/ | |||||
| 269 | ~/.cargo/registry/index/ | |||||
| 270 | ~/.cargo/registry/cache/ | |||||
| 271 | ~/.cargo/git/db/ | |||||
| 272 | target/ | |||||
| 273 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |||||
| 274 | ||||||
| 275 | - name: Check formatting | |||||
| 276 | run: cargo fmt -- --check | |||||
| 277 | ||||||
| 278 | - name: Run clippy | |||||
| 279 | run: cargo clippy -- -D warnings | |||||
| 280 | ||||||
| 281 | - name: Run tests | |||||
| 282 | run: cargo test --verbose | |||||
| 283 | ||||||
| 284 | - name: Build release | |||||
| 285 | run: cargo build --release --verbose | |||||
| 286 | YAML | |||||
| 287 | } | |||||
| 288 | ||||||
| 289 | 0 0 | sub _generate_go_workflow() { | ||||
| 290 | 0 | return <<'YAML'; | ||||
| 291 | --- | |||||
| 292 | name: Go CI | |||||
| 293 | ||||||
| 294 | 'on': | |||||
| 295 | push: | |||||
| 296 | branches: | |||||
| 297 | - main | |||||
| 298 | pull_request: | |||||
| 299 | branches: | |||||
| 300 | - main | |||||
| 301 | ||||||
| 302 | concurrency: | |||||
| 303 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 304 | cancel-in-progress: true | |||||
| 305 | ||||||
| 306 | permissions: | |||||
| 307 | contents: read | |||||
| 308 | ||||||
| 309 | jobs: | |||||
| 310 | test: | |||||
| 311 | runs-on: ubuntu-latest | |||||
| 312 | steps: | |||||
| 313 | - name: Checkout code | |||||
| 314 | uses: actions/checkout@v6 | |||||
| 315 | ||||||
| 316 | - name: Setup Go | |||||
| 317 | uses: actions/setup-go@v5 | |||||
| 318 | with: | |||||
| 319 | go-version: '1.22' | |||||
| 320 | ||||||
| 321 | - name: Cache Go modules | |||||
| 322 | uses: actions/cache@v5 | |||||
| 323 | with: | |||||
| 324 | path: ~/go/pkg/mod | |||||
| 325 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |||||
| 326 | restore-keys: | | |||||
| 327 | ${{ runner.os }}-go- | |||||
| 328 | ||||||
| 329 | - name: Download dependencies | |||||
| 330 | run: go mod download | |||||
| 331 | ||||||
| 332 | - name: Run go vet | |||||
| 333 | run: go vet ./... | |||||
| 334 | ||||||
| 335 | - name: Run tests | |||||
| 336 | run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... | |||||
| 337 | ||||||
| 338 | - name: Build | |||||
| 339 | run: go build -v ./... | |||||
| 340 | YAML | |||||
| 341 | } | |||||
| 342 | ||||||
| 343 | 0 0 | sub _generate_ruby_workflow() { | ||||
| 344 | 0 | return <<'YAML'; | ||||
| 345 | --- | |||||
| 346 | name: Ruby CI | |||||
| 347 | ||||||
| 348 | 'on': | |||||
| 349 | push: | |||||
| 350 | branches: | |||||
| 351 | - main | |||||
| 352 | pull_request: | |||||
| 353 | branches: | |||||
| 354 | - main | |||||
| 355 | ||||||
| 356 | concurrency: | |||||
| 357 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 358 | cancel-in-progress: true | |||||
| 359 | ||||||
| 360 | permissions: | |||||
| 361 | contents: read | |||||
| 362 | ||||||
| 363 | jobs: | |||||
| 364 | test: | |||||
| 365 | runs-on: ubuntu-latest | |||||
| 366 | strategy: | |||||
| 367 | matrix: | |||||
| 368 | ruby-version: | |||||
| 369 | - '3.1' | |||||
| 370 | - '3.2' | |||||
| 371 | - '3.3' | |||||
| 372 | steps: | |||||
| 373 | - name: Checkout code | |||||
| 374 | uses: actions/checkout@v6 | |||||
| 375 | ||||||
| 376 | - name: Set up Ruby | |||||
| 377 | uses: ruby/setup-ruby@v1 | |||||
| 378 | with: | |||||
| 379 | ruby-version: ${{ matrix.ruby-version }} | |||||
| 380 | bundler-cache: true | |||||
| 381 | ||||||
| 382 | - name: Run tests | |||||
| 383 | run: bundle exec rake test | |||||
| 384 | YAML | |||||
| 385 | } | |||||
| 386 | ||||||
| 387 | 0 0 | sub _generate_docker_workflow() { | ||||
| 388 | 0 | return <<'YAML'; | ||||
| 389 | --- | |||||
| 390 | name: Docker Build | |||||
| 391 | ||||||
| 392 | 'on': | |||||
| 393 | push: | |||||
| 394 | branches: | |||||
| 395 | - main | |||||
| 396 | tags: | |||||
| 397 | - v* | |||||
| 398 | pull_request: | |||||
| 399 | branches: | |||||
| 400 | - main | |||||
| 401 | ||||||
| 402 | concurrency: | |||||
| 403 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 404 | cancel-in-progress: true | |||||
| 405 | ||||||
| 406 | permissions: | |||||
| 407 | contents: read | |||||
| 408 | packages: write | |||||
| 409 | ||||||
| 410 | jobs: | |||||
| 411 | build: | |||||
| 412 | runs-on: ubuntu-latest | |||||
| 413 | steps: | |||||
| 414 | - name: Checkout code | |||||
| 415 | uses: actions/checkout@v6 | |||||
| 416 | ||||||
| 417 | - name: Set up Docker Buildx | |||||
| 418 | uses: docker/setup-buildx-action@v3 | |||||
| 419 | ||||||
| 420 | - name: Log in to Docker Hub | |||||
| 421 | uses: docker/login-action@v3 | |||||
| 422 | with: | |||||
| 423 | username: ${{ secrets.DOCKER_USERNAME }} | |||||
| 424 | password: ${{ secrets.DOCKER_PASSWORD }} | |||||
| 425 | if: github.event_name != 'pull_request' | |||||
| 426 | ||||||
| 427 | - name: Extract metadata | |||||
| 428 | id: meta | |||||
| 429 | uses: docker/metadata-action@v5 | |||||
| 430 | with: | |||||
| 431 | images: your-username/your-image | |||||
| 432 | ||||||
| 433 | - name: Build and push | |||||
| 434 | uses: docker/build-push-action@v5 | |||||
| 435 | with: | |||||
| 436 | context: . | |||||
| 437 | push: ${{ github.event_name != 'pull_request' }} | |||||
| 438 | tags: ${{ steps.meta.outputs.tags }} | |||||
| 439 | labels: ${{ steps.meta.outputs.labels }} | |||||
| 440 | cache-from: type=gha | |||||
| 441 | cache-to: type=gha,mode=max | |||||
| 442 | YAML | |||||
| 443 | } | |||||
| 444 | ||||||
| 445 | 0 0 | sub _generate_static_workflow() { | ||||
| 446 | 0 | return <<'YAML'; | ||||
| 447 | --- | |||||
| 448 | name: Deploy Static Site | |||||
| 449 | ||||||
| 450 | 'on': | |||||
| 451 | push: | |||||
| 452 | branches: | |||||
| 453 | - main | |||||
| 454 | ||||||
| 455 | permissions: | |||||
| 456 | contents: read | |||||
| 457 | pages: write | |||||
| 458 | id-token: write | |||||
| 459 | ||||||
| 460 | concurrency: | |||||
| 461 | group: pages | |||||
| 462 | cancel-in-progress: false | |||||
| 463 | ||||||
| 464 | jobs: | |||||
| 465 | build: | |||||
| 466 | runs-on: ubuntu-latest | |||||
| 467 | steps: | |||||
| 468 | - name: Checkout | |||||
| 469 | uses: actions/checkout@v6 | |||||
| 470 | ||||||
| 471 | - name: Setup Pages | |||||
| 472 | uses: actions/configure-pages@v4 | |||||
| 473 | ||||||
| 474 | - name: Build | |||||
| 475 | run: echo "Add your build command here" | |||||
| 476 | ||||||
| 477 | - name: Upload artifact | |||||
| 478 | uses: actions/upload-pages-artifact@v3 | |||||
| 479 | with: | |||||
| 480 | path: ./public | |||||
| 481 | ||||||
| 482 | deploy: | |||||
| 483 | environment: | |||||
| 484 | name: github-pages | |||||
| 485 | url: ${{ steps.deployment.outputs.page_url }} | |||||
| 486 | runs-on: ubuntu-latest | |||||
| 487 | needs: build | |||||
| 488 | steps: | |||||
| 489 | - name: Deploy to GitHub Pages | |||||
| 490 | id: deployment | |||||
| 491 | uses: actions/deploy-pages@v4 | |||||
| 492 | YAML | |||||
| 493 | } | |||||
| 494 | ||||||
| 495 | 0 0 | sub _generate_java_workflow() { | ||||
| 496 | 0 | return <<'YAML'; | ||||
| 497 | --- | |||||
| 498 | name: Java CI | |||||
| 499 | ||||||
| 500 | 'on': | |||||
| 501 | push: | |||||
| 502 | branches: | |||||
| 503 | - main | |||||
| 504 | - develop | |||||
| 505 | pull_request: | |||||
| 506 | branches: | |||||
| 507 | - main | |||||
| 508 | - develop | |||||
| 509 | ||||||
| 510 | concurrency: | |||||
| 511 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 512 | cancel-in-progress: true | |||||
| 513 | ||||||
| 514 | permissions: | |||||
| 515 | contents: read | |||||
| 516 | ||||||
| 517 | jobs: | |||||
| 518 | test: | |||||
| 519 | runs-on: ubuntu-latest | |||||
| 520 | strategy: | |||||
| 521 | matrix: | |||||
| 522 | java-version: | |||||
| 523 | - '11' | |||||
| 524 | - '17' | |||||
| 525 | - '21' | |||||
| 526 | steps: | |||||
| 527 | - name: Checkout code | |||||
| 528 | uses: actions/checkout@v6 | |||||
| 529 | ||||||
| 530 | - name: Set up JDK ${{ matrix.java-version }} | |||||
| 531 | uses: actions/setup-java@v4 | |||||
| 532 | with: | |||||
| 533 | java-version: ${{ matrix.java-version }} | |||||
| 534 | distribution: 'temurin' | |||||
| 535 | ||||||
| 536 | - name: Cache Maven packages | |||||
| 537 | uses: actions/cache@v5 | |||||
| 538 | with: | |||||
| 539 | path: ~/.m2/repository | |||||
| 540 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} | |||||
| 541 | restore-keys: | | |||||
| 542 | ${{ runner.os }}-maven- | |||||
| 543 | ||||||
| 544 | - name: Build with Maven | |||||
| 545 | run: mvn -B package --file pom.xml | |||||
| 546 | ||||||
| 547 | - name: Run tests | |||||
| 548 | run: mvn -B test | |||||
| 549 | ||||||
| 550 | - name: Generate test report | |||||
| 551 | if: always() | |||||
| 552 | run: mvn surefire-report:report | |||||
| 553 | YAML | |||||
| 554 | } | |||||
| 555 | ||||||
| 556 | 0 0 | sub _generate_cpp_workflow() { | ||||
| 557 | 0 | return <<'YAML'; | ||||
| 558 | --- | |||||
| 559 | name: C++ CI | |||||
| 560 | ||||||
| 561 | 'on': | |||||
| 562 | push: | |||||
| 563 | branches: | |||||
| 564 | - main | |||||
| 565 | pull_request: | |||||
| 566 | branches: | |||||
| 567 | - main | |||||
| 568 | ||||||
| 569 | concurrency: | |||||
| 570 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 571 | cancel-in-progress: true | |||||
| 572 | ||||||
| 573 | permissions: | |||||
| 574 | contents: read | |||||
| 575 | ||||||
| 576 | jobs: | |||||
| 577 | test: | |||||
| 578 | runs-on: ${{ matrix.os }} | |||||
| 579 | strategy: | |||||
| 580 | matrix: | |||||
| 581 | os: | |||||
| 582 | - ubuntu-latest | |||||
| 583 | - macos-latest | |||||
| 584 | - windows-latest | |||||
| 585 | build-type: | |||||
| 586 | - Debug | |||||
| 587 | - Release | |||||
| 588 | steps: | |||||
| 589 | - name: Checkout code | |||||
| 590 | uses: actions/checkout@v6 | |||||
| 591 | ||||||
| 592 | - name: Install CMake | |||||
| 593 | uses: lukka/get-cmake@latest | |||||
| 594 | ||||||
| 595 | - name: Cache build artifacts | |||||
| 596 | uses: actions/cache@v5 | |||||
| 597 | with: | |||||
| 598 | path: | | |||||
| 599 | build | |||||
| 600 | ~/.cache/ccache | |||||
| 601 | key: ${{ runner.os }}-${{ matrix.build-type }}-${{ hashFiles('**/CMakeLists.txt') }} | |||||
| 602 | ||||||
| 603 | - name: Configure CMake | |||||
| 604 | run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} | |||||
| 605 | ||||||
| 606 | - name: Build | |||||
| 607 | run: cmake --build build --config ${{ matrix.build-type }} | |||||
| 608 | ||||||
| 609 | - name: Run tests | |||||
| 610 | working-directory: build | |||||
| 611 | run: ctest -C ${{ matrix.build-type }} --output-on-failure | |||||
| 612 | YAML | |||||
| 613 | } | |||||
| 614 | ||||||
| 615 | 0 0 | sub _generate_php_workflow() { | ||||
| 616 | 0 | return <<'YAML'; | ||||
| 617 | --- | |||||
| 618 | name: PHP CI | |||||
| 619 | ||||||
| 620 | 'on': | |||||
| 621 | push: | |||||
| 622 | branches: | |||||
| 623 | - main | |||||
| 624 | - develop | |||||
| 625 | pull_request: | |||||
| 626 | branches: | |||||
| 627 | - main | |||||
| 628 | - develop | |||||
| 629 | ||||||
| 630 | concurrency: | |||||
| 631 | group: ${{ github.workflow }}-${{ github.ref }} | |||||
| 632 | cancel-in-progress: true | |||||
| 633 | ||||||
| 634 | permissions: | |||||
| 635 | contents: read | |||||
| 636 | ||||||
| 637 | jobs: | |||||
| 638 | test: | |||||
| 639 | runs-on: ubuntu-latest | |||||
| 640 | strategy: | |||||
| 641 | matrix: | |||||
| 642 | php-version: | |||||
| 643 | - '8.1' | |||||
| 644 | - '8.2' | |||||
| 645 | - '8.3' | |||||
| 646 | steps: | |||||
| 647 | - name: Checkout code | |||||
| 648 | uses: actions/checkout@v6 | |||||
| 649 | ||||||
| 650 | - name: Setup PHP ${{ matrix.php-version }} | |||||
| 651 | uses: shivammathur/setup-php@v2 | |||||
| 652 | with: | |||||
| 653 | php-version: ${{ matrix.php-version }} | |||||
| 654 | extensions: mbstring, xml, ctype, json | |||||
| 655 | coverage: xdebug | |||||
| 656 | ||||||
| 657 | - name: Validate composer.json | |||||
| 658 | run: composer validate --strict | |||||
| 659 | ||||||
| 660 | - name: Cache Composer packages | |||||
| 661 | uses: actions/cache@v5 | |||||
| 662 | with: | |||||
| 663 | path: vendor | |||||
| 664 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} | |||||
| 665 | restore-keys: | | |||||
| 666 | ${{ runner.os }}-php- | |||||
| 667 | ||||||
| 668 | - name: Install dependencies | |||||
| 669 | run: composer install --prefer-dist --no-progress | |||||
| 670 | ||||||
| 671 | - name: Run PHPUnit tests | |||||
| 672 | run: vendor/bin/phpunit --coverage-text | |||||
| 673 | ||||||
| 674 | - name: Run PHP CodeSniffer | |||||
| 675 | run: vendor/bin/phpcs --standard=PSR12 src tests | |||||
| 676 | continue-on-error: true | |||||
| 677 | YAML | |||||
| 678 | } | |||||
| 679 | ||||||
| 680 - 691 | =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 | |||||
| 692 | ||||||
| 693 | 1; | |||||