I've got the following GitHub ci.yml
workflow where I have created separate jobs to handle the pipeline for my project:
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/
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