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

Avatar for Lars Gyrup Brink Nielsen

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