Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid action/cache setup repetition in GitHub Action

I've got the following GitHub ci.yml workflow where I have created separate jobs to handle the pipeline for my project:

enter image description here

This is the YAML file

name: CI
on:
  pull_request:
    branches:
      - develop
  push:
    branches:
      - develop

jobs:
  valid-title:
    name: Validate Title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  setup:
    name: Setup
    needs: [valid-title]
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16]
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"

      - uses: actions/cache@v3
        id: npm-cache
        with:
          path: "**/node_modules"
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci

  lint:
    name: Static Analysis
    needs: [setup]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"

      - uses: actions/cache@v3
        id: npm-cache
        with:
          path: ./node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: Static analysis
        run: npm run lint

  test:
    name: Unit Testing
    needs: [setup]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"

      - uses: actions/cache@v3
        id: npm-cache
        with:
          path: ./node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci
      - name: Unit Tests
        run: npm run test:unit

  build:
    name: Build
    needs: [setup]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"

      - uses: actions/cache@v3
        id: npm-cache
        with:
          path: ./node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci
      - name: Build Library
        run: npm run build

  integration:
    name: Integration Tests
    if: github.event.pull_request.draft == false
    needs: [lint, test, build]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"

      - uses: actions/cache@v3
        id: npm-cache
        with:
          path: ./node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: Integration Tests
        run: echo "placeholder for integration run"
        env:
          PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


As you can see, for each job I am forced to copy and paste the following setup

- uses: actions/checkout@v3

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"

      - uses: actions/cache@v3
        id: npm-cache
        with:
          path: ./node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci

How can I extract it and reuse it to avoid this duplication/copy-pasting?

I don't want to setup an external repo just to create a composite, but I could not leverage Reusable Workflow as part of existing steps of a job.

So I am kinda lost/

like image 876
floroz Avatar asked Feb 03 '26 11:02

floroz


1 Answers

You can create "local" composite actions in the same repository, as the documentation specifies:

If you're building an action that you don't plan to make available to others, you can store the action's files in any location in your repository. If you plan to combine action, workflow, and application code in a single repository, we recommend storing actions in the .github directory. For example, .github/actions/action-a and .github/actions/action-b.

So, you'd have a local path in your repository as

.github
├── actions
│   └── setup-node
│       └── action.yaml
└── workflows
    └── pr.yaml

Then in your workflow just refer to it with:

jobs:
  foo:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: ./.github/actions/setup-node

Note that you should use actions/checkout@v3 before you use the local composite action

like image 153
Fcmam5 Avatar answered Feb 05 '26 09:02

Fcmam5



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!