Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The world's most elaborate CI workflow for an A...

The world's most elaborate CI workflow for an Angular library

Using a GitHub Actions workflow running 50 jobs per workflow run, Node.js, and SonarCloud, Lumberjack maintains end-to-end compatibility across several versions of Angular and TypeScript in a single codebase.

Presented at:
- GitHub Satellite India 2021 https://youtu.be/2KySyHU3fKo

Lars Gyrup Brink Nielsen

March 21, 2021
Tweet

More Decks by Lars Gyrup Brink Nielsen

Other Decks in Programming

Transcript

  1. Lumberjack features Lumberjack is a versatile and extensible logging library

    for Angular. • Configurable logging with 6 severity levels • Robust error handling • Plugin-based architecture • Built-in log drivers: • Browser console log driver • HTTP log driver • Angular schematics code generation and codemods • Verified cross-version Angular compatibility Lumberjack Application Log drivers Log drivers Log drivers
  2. Log levels • Default log levels: • Development: All log

    levels are enabled • Production: All log levels except Debug and Trace are enabled • Default log levels can be overridden • Log levels are configurable on a per-log driver basis
  3. The problem • 8 Angular versions • 6 TypeScript versions

    • 2 Node.js versions • 30 possible combinations of dependencies Angular CLI version Angular version Node.js version TypeScript version 9.0.7 9.0.x 10.13.x/12.11.x or later minor version 3.6.x/3.7.x 9.1.x 9.1.x 10.13.x/12.11.x or later minor version 3.6.x/3.7.x/3.8.x 10.0.8 10.0.x 10.13.x/12.11.x or later minor version 3.9.x 10.1.7 10.1.x 10.13.x/12.11.x or later minor version 3.9.x/4.0.x 10.2.x 10.2.x 10.13.x/12.11.x or later minor version 3.9.x/4.0.x 11.0.7 11.0.x 10.13.x/12.11.x or later minor version 4.0.x 11.1.x 11.1.x 10.13.x/12.11.x or later minor version 4.0.x/4.1.x 11.2.x 11.2.x 10.13.x/12.11.x or later minor version 4.0.x/4.1.x
  4. The solution • Angular CLI workspace • Single-source codebase solution

    • 1 demo application • 1 end-to-end application test suite • 1 schematics target application • 1 schematics end-to-end test suite • A GitHub Actions job run per combination of dependencies • Node.js scripts
  5. 50 jobs per CI run • 49 GitHub Actions job

    runs • 10-30 job runs in parallel • ~6 minutes in total
  6. 50 jobs per CI run The build, lint, and sonar

    jobs • The build job: Production library build, latest versions • The lint job: Check formatting and linting rules, latest versions • The sonar job: Generate test coverage and lint reports, then upload them to SonarCloud
  7. 50 jobs per CI run The lib job • Node.js:

    12.x • Angular versions: • 9.0.x, 9.1.x • 10.0.x, 10.1.x, 10.2.x • 11.0.x, 11.1.x, 11.2.x • TypeScript versions: • 3.7.x, 3.8.x, 3.9.x • 4.0.x, 4.1.x
  8. The lib job • 8 matrix legs: • Install Angular

    matrix leg version • Install associated TypeScript version • Run unit and integration tests for: • Development library projects • Publishable library projects • Angular schematics
  9. 50 jobs per CI run The app job • Node.js

    versions: • 10.x • 12.x • Angular versions: • 9.0.x, 9.1.x • 10.0.x, 10.1.x, 10.2.x • 11.0.x, 11.1.x, 11.2.x • TypeScript versions: • 3.7.x, 3.8.x, 3.9.x • 4.0.x, 4.1.x
  10. The app job • 16 matrix legs: • Install Node.js

    matrix leg version • Install Angular matrix leg version • Install associated TypeScript version • Delete local TypeScript path mappings • Download build artifact from ”build” job • Move Lumberjack package into node_modules • Run Angular Compatibility Compiler (NGCC) • Run demo application unit and integration tests • Run demo application production build
  11. 50 jobs per CI run The e2e job • Node.js:

    12.x • Angular versions: • 9.0.x, 9.1.x • 10.0.x, 10.1.x, 10.2.x • 11.0.x, 11.1.x, 11.2.x • TypeScript versions: • 3.7.x, 3.8.x, 3.9.x • 4.0.x, 4.1.x
  12. The e2e job • 8 matrix legs: • Install Angular

    matrix leg version • Install associated TypeScript version • Delete local TypeScript path mappings • Download build artifact from ”build” job • Move Lumberjack package into node_modules • Run Angular Compatibility Compiler (NGCC) • Install latest Google Chrome • Run end-to-end tests for demo application
  13. 50 jobs per CI run The schematics-e2e job • Node.js

    versions: • 10.x • 12.x • Angular versions: • 9.1.x • 10.0.x, 10.1.x, 10.2.x • 11.0.x, 11.1.x, 11.2.x • TypeScript versions: • 3.7.x, 3.8.x, 3.9.x • 4.0.x, 4.1.x
  14. The schematics-e2e job • 14 matrix legs: • Install Node.js

    matrix leg version • Install Angular matrix leg version • Install associated TypeScript version • Delete local TypeScript path mappings • Download build artifact from ”build” job • Move Lumberjack package into node_modules • Run Angular Compatibility Compiler (NGCC) • Run end-to-end tests for schematics
  15. How our GitHub workflow matrix is configured app: runs-on: ubuntu-latest

    needs: build strategy: matrix: node-version: [10.x, 12.x] angular-version: [9.0.x, 9.1.x, 10.0.x, 10.1.x, 10.2.x, 11.0.x, 11.1.x, 11.2.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 # 👈 with: node-version: ${{ matrix.node-version }} - name: Use Angular version ${{ matrix.angular-version }} uses: ngworker/angular-versions-action@v3 with: angular-version: ${{ matrix.angular-version }} # Yarn caching left out for brevity - run: yarn install # Intermediary steps left out for brevity - run: yarn test:ci - run: yarn build
  16. How our GitHub workflow matrix is configured app: runs-on: ubuntu-latest

    needs: build strategy: matrix: node-version: [10.x, 12.x] # 👈 angular-version: [9.0.x, 9.1.x, 10.0.x, 10.1.x, 10.2.x, 11.0.x, 11.1.x, 11.2.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} # 👈 - name: Use Angular version ${{ matrix.angular-version }} uses: ngworker/angular-versions-action@v3 with: angular-version: ${{ matrix.angular-version }} # Yarn caching left out for brevity - run: yarn install # Intermediary steps left out for brevity - run: yarn test:ci - run: yarn build
  17. How our GitHub workflow matrix is configured app: runs-on: ubuntu-latest

    needs: build strategy: matrix: node-version: [10.x, 12.x] angular-version: [9.0.x, 9.1.x, 10.0.x, 10.1.x, 10.2.x, 11.0.x, 11.1.x, 11.2.x] # 👆 steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - name: Use Angular version ${{ matrix.angular-version }} uses: ngworker/angular-versions-action@v3 with: angular-version: ${{ matrix.angular-version }} # 👈 # Yarn caching left out for brevity - run: yarn install # Intermediary steps left out for brevity - run: yarn test:ci - run: yarn build
  18. How our GitHub workflow matrix is configured app: runs-on: ubuntu-latest

    needs: build strategy: matrix: node-version: [10.x, 12.x] angular-version: [9.0.x, 9.1.x, 10.0.x, 10.1.x, 10.2.x, 11.0.x, 11.1.x, 11.2.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - name: Use Angular version ${{ matrix.angular-version }} uses: ngworker/angular-versions-action@v3 # 👈 with: angular-version: ${{ matrix.angular-version }} # Yarn caching left out for brevity - run: yarn install # Intermediary steps left out for brevity - run: yarn test:ci - run: yarn build
  19. ngworker/angular-versions-action • Input parameter: angular-version • Example value: [11.0.x, 11.1.x,

    11.2.x] • Replaces >20 Angular and related dependencies such as TypeScript in package.json • Combinations of dependencies verified to still be in a working state
  20. Cross-version compatibility • Simple single-source codebase solution • Purpose-built GitHub

    Action for Angular dependency management in CI workflows • Fast, parallellized GitHub Actions workflow • Each combination of dependencies is run in isolation for: • Unit and integration tests • End-to-end tests • Angular schematics end-to-end tests
  21. Cross-version compatibility • We release features and patches across 8

    Angular versions, 6 TypeScript versions, and 2 Node.js versions from a single-source codebase • Backward-incompatible API and syntax usage is immediately detected • Verified support for new Angular, TypeScript, and Node.js versions is usually as simple as adding a value to a list parameter in our CI workflow