Skip to content

Latest commit

 

History

History
256 lines (177 loc) · 8.81 KB

File metadata and controls

256 lines (177 loc) · 8.81 KB

Job 1: Linting

Expand

Solution:

lint:
  runs-on: ubuntu-24.04
  steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: 22
        cache: "npm"

    - name: Install dependencies
      run: npm ci

    - name: Run lint
      run: npm run lint

Explanation:

  • runs-on: ubuntu-24.04: This specifies that the job will run on the latest Ubuntu environment.
  • actions/checkout@v4: This step checks out the repository's code.
  • biomejs/setup-biome@v2: This sets up the Biome CLI tool to run linting.
  • biome ci: This runs the Biome CLI with the ci command to check for linting issues.

What you’ve learned:

Skills acquired:

  • 📦 Basic GitHub Actions usage: You used actions/checkout@v4 to fetch the repository code, and actions/setup-node@v4 to configure the Node.js environment.
  • 🧹 Code quality checks: You integrated a linter (Biome) to automatically detect style issues, bugs, and inconsistencies in the codebase.
  • ⚡️ Workflow optimization: By using the npm cache with cache: "npm", you’ve seen how caching can significantly reduce CI execution time.

Why it matters:

Linting enforces clean, consistent code formatting and helps prevent common issues early. Automating this step ensures that every contributor follows the same coding standards, reducing noise during code reviews.

Job 2: Type Checking

Expand

Solution:

verify-typescript-types:
  runs-on: ubuntu-24.04
  steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: 22
        cache: "npm"

    - name: Install dependencies
      run: npm ci

    - name: Verify typescript types
      run: npm run typing-check

Explanation:

  • actions/setup-node@v4: This action sets up the Node.js environment, including caching npm dependencies to speed up future runs.

  • npm ci: This installs the project's dependencies from the package-lock.

  • npm run typing-check: This runs the type-checking script to ensure there are no TypeScript errors in the code.

What you’ve learned:

Skills acquired:

  • 👓 Static analysis: By running npm run typing-check, you executed a static TypeScript check to catch potential issues without running the code.
  • 🔄 Reusing workflow patterns: This job follows the same structure as the linting one, showing how consistent, reusable workflow design makes pipelines easier to manage.
  • 📘 Separation of concerns: Each job is focused on a single responsibility, improving clarity and maintainability of the CI configuration.

Why it matters:

Strong type checking helps catch bugs before runtime, increasing confidence in your codebase. Automating this guarantees type safety throughout the development lifecycle.

Job 3: Test Coverage

Expand

Solution:

code-coverage:
  runs-on: ubuntu-24.04
  steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: 22
        cache: "npm"

    - name: Install dependencies
      run: npm ci

    - name: Run code coverage
      run: npm run coverage

    - name: Report Coverage
      if: always()
      uses: davelosert/vitest-coverage-report-action@v2

Explanation:

  • actions/setup-node@v4: This action sets up the Node.js environment, including caching npm dependencies to speed up future runs.

  • npm ci: This installs the project's dependencies from the package-lock.

  • npm run coverage: This command runs the tests and generates coverage reports.

  • davelosert/vitest-coverage-report-action@v2: This action is used to report the coverage results. The if: always() ensures that the coverage report is generated regardless of whether the tests pass or fail.

What you've learned:

Skills acquired:

  • ✅ Running tests in CI: You configured GitHub Actions to automatically execute the test suite using npm run coverage.
  • 📊 Generating and reporting code coverage: You used the third-party action davelosert/vitest-coverage-report-action@v2 to visualize coverage results.
  • 🧩 Using external actions: You explored how to integrate community actions to enhance CI/CD capabilities.

Why it matters:

Test coverage highlights which parts of the code are tested and which aren't, helping teams identify gaps and prioritize test writing. Reporting this coverage ensures visibility and encourages better test practices.

Job 4: Docker Build and Push

Expand

Solution:

build-and-push:
  needs: [lint, verify-typescript-types, code-coverage]
  runs-on: ubuntu-24.04
  permissions:
    contents: read
    packages: write
  steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3

    - name: Log in to GitHub Container Registry
      uses: docker/login-action@v3
      with:
        registry: ghcr.io
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    - name: Extract metadata for Docker
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: ghcr.io/${{ github.repository }}
        tags: |
          type=ref,event=branch
          type=sha,format=short

    - name: Build and push Docker image
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        platforms: linux/amd64,linux/arm64
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

Explanation:

  • needs: [lint, verify-typescript-types, code-coverage]: This ensures the job only runs after the previous jobs have completed successfully, creating a pipeline.

  • permissions: Explicitly sets the required permissions for the GITHUB_TOKEN to read repository contents and write to the GitHub Packages registry.

  • docker/setup-buildx-action@v3: Sets up Docker Buildx, which provides enhanced build capabilities including better caching and multi-platform builds.

  • docker/login-action@v3: Authenticates with GitHub Container Registry using the automatically provided GITHUB_TOKEN.

  • docker/metadata-action@v5: Extracts metadata from Git to create appropriate tags and labels for the Docker image:

    • type=ref,event=branch: Tags the image with the branch name (e.g., main)
    • type=sha,format=short: Tags the image with the short Git commit SHA for easier identification
  • docker/build-push-action@v5: Builds and pushes the Docker image with:

    • Multi-platform support for both AMD64 (standard x86 processors) and ARM64 (like Apple Silicon)
    • GitHub Actions cache integration for faster builds
    • Tags and labels from the metadata action
    • Automatic push to the registry

What you've learned:

Skills acquired:

  • 🔄 CI/CD Pipeline Construction: You've created a complete pipeline from code quality checks to deployment, learning how jobs can depend on each other with the needs keyword.
  • 🐳 Docker Integration: You've learned how to build and push multi-architecture Docker images (AMD64 and ARM64) as part of your CI/CD pipeline.
  • 🔑 Secure Authentication: You've used GitHub's built-in token system to securely authenticate with the container registry without exposing credentials.
  • 🏷️ Image Tagging Strategies: You've implemented best practices for versioning container images using Git metadata.
  • 🚀 Deployment Automation: You've automated the deployment process, ensuring that only code that passes quality checks gets deployed.

Why it matters:

Containerization is a critical part of modern application deployment. By automating the build and push process, you ensure consistent, reproducible deployments and eliminate manual steps that could introduce errors. This completes the CI/CD pipeline, taking your code from commit to deployable artifact.

Using your container image:

Once pushed, your image will be available at ghcr.io/ekino/githubworkflow-handson-nodejs with two tags:

  • Branch name tag: ghcr.io/ekino/githubworkflow-handson-nodejs:main (or your branch name)
  • Short SHA tag: ghcr.io/ekino/githubworkflow-handson-nodejs:a1b2c3d (abbreviated commit hash)

You can pull either version:

# Pull by branch name
docker pull ghcr.io/ekino/githubworkflow-handson-nodejs:main

# Pull by specific commit
docker pull ghcr.io/ekino/githubworkflow-handson-nodejs:a1b2c3d

The multi-architecture support means the same image works on both Intel/AMD machines and ARM-based systems like Apple Silicon Macs.