Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 55 additions & 11 deletions .github/workflows/test-action-yarn-cache.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
name: Test Yarn Cache Action
name: Test Yarn Cache

on:
pull_request:
paths: [actions/yarn-cache/**]
paths:
- .github/workflows/yarn-cache.yml
- actions/yarn-cache/**
- actions/yarn-cache-key/**
- yarn-cache.yml

concurrency:
group: test-action-yarn-cache-${{ github.head_ref }}
cancel-in-progress: true

env:
CACHE_PATH: |
Expand All @@ -12,29 +20,65 @@ env:
WORKING_DIR: ./test/actions/yarn-cache

jobs:
first-cache:
create-cache:
uses: ./.github/workflows/yarn-cache.yml
with:
cache-path: |
~/.cache
test/actions/yarn-cache/.yarn/unplugged
test/actions/yarn-cache/.yarn/install-state.gz
working-directory: ./test/actions/yarn-cache

use-exact-cache:
needs: [create-cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version-file: test/actions/yarn-cache/.nvmrc
node-version-file: ${{ env.WORKING_DIR }}/.nvmrc
- run: corepack enable
- uses: ./actions/yarn-cache
- uses: ./.github/actions/yarn-cache
id: cache
with:
cache_path: ${{ env.CACHE_PATH }}
cache-path: ${{ env.CACHE_PATH }}
working-directory: ${{ env.WORKING_DIR }}
- if: steps.cache.outputs.cache-hit != 'true'
run: |
echo "::error::The cache wasn't used"
exit 1

second-cache:
needs: [first-cache]
use-partial-cache:
needs: [create-cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version-file: test/actions/yarn-cache/.nvmrc
node-version-file: ${{ env.WORKING_DIR }}/.nvmrc
- run: corepack enable
- uses: ./actions/yarn-cache
- working-directory: ${{ env.WORKING_DIR }}
run: yarn add express@^5.2.1
- uses: ./.github/actions/yarn-cache-key
id: key
with:
working-directory: ${{ env.WORKING_DIR }}
- uses: ./.github/actions/yarn-cache
id: cache
with:
cache_path: ${{ env.CACHE_PATH }}
cache-path: ${{ env.CACHE_PATH }}
working-directory: ${{ env.WORKING_DIR }}
- if: steps.cache.outputs.cache-hit == 'true'
run: | # shell
echo "::error::Expected a restore-key match, not an exact cache hit"
exit 1

clean-up:
needs: [create-cache, use-exact-cache, use-partial-cache]
if: always()
runs-on: ubuntu-latest
steps:
- env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: gh cache delete --all
89 changes: 58 additions & 31 deletions .github/workflows/yarn-cache.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,70 @@
name: Yarn Cache

# description: | #markdown
# Similar idea to the yarn-cache action, but makes sure that only one workflow
# can create the cache at a time. EG:

# ```yaml
# jobs:
# cache:
# uses: johngeorgewright/workflows/workflows/yarn-cache@main
# test:
# needs: [cache]
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v6
#
# # OPTION 1: manually download the cache
# - uses: actions/cache/restore@v5
# with:
# key: ${\{ needs.cache.outputs.key }}
# path: ${\{ needs.cache.outputs.path }}
# restore-keys: ${\{ needs.cache.outputs.restore-keys }}
#
# # OPTION 2: let the key be discovered automatically
# - uses: actions/setup-node@v6
# - uses: johngeorgewright/workflows/actions/yarn-cache@main
# ```

on:
workflow_call:
inputs:
cache-path:
description: The cache paths
required: false
type: string
default: |
~/.cache
.yarn/unplugged
.yarn/install-state.gz

runs-on:
default: ubuntu-latest
required: false
type: string
description: Use runs-on to define the type of machine to run the job on.

working-directory:
description: Optional directory to execute yarn command in
required: false
type: string
default: ${{ github.workspace }}

outputs:
key:
value: ${{ jobs.key.outputs.cache-key }}
path:
value: ${{ jobs.prime.outputs.cache-path }}
restore-keys:
value: ${{ jobs.key.outputs.cache-restore-keys }}

jobs:
deprecate:
name: Deprecated
runs-on: ${{ inputs.runs-on }}
steps:
- name: Message
run: echo "::warning title=Deprecated workflow::The johngeorgewright/workflows/.github/workflows/yarn-cache.yml is dperecated. Please use johngeorgewright/workflows/yarn-cache.yml instead."

key:
name: Key
runs-on: ${{ inputs.runs-on }}
outputs:
cache-key: ${{ steps.key.outputs.cache_key }}
cache-key: ${{ steps.key.outputs.cache-key }}
cache-restore-keys: ${{ steps.key.outputs.cache-restore-keys }}
steps:
- name: Checkout project
uses: actions/checkout@v6
Expand All @@ -36,46 +73,36 @@ jobs:
id: node
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
node-version-file: ${{ inputs.working-directory }}/.nvmrc

- run: corepack enable

- name: Key
id: key
run: |
corepack enable
echo "cache_key=${{ runner.os }}-node-${{ steps.node.outputs.node-version }}-yarn-$(yarn --version)-${{ hashFiles('**/yarn.lock') }}" >> $GITHUB_OUTPUT
uses: johngeorgewright/workflows/actions/yarn-cache-key@main
with:
working-directory: ${{ inputs.working-directory }}

prime:
name: Prime
needs: [key]
runs-on: ${{ inputs.runs-on }}
env:
CACHE_PATH: |
~/.cache
.yarn/unplugged
.yarn/install-state.gz
concurrency:
group: ${{ needs.key.outputs.cache-key }}
outputs:
cache-path: ${{ env.CACHE_PATH }}
cache-path: ${{ inputs.cache-path }}
steps:
- name: Checkout project
uses: actions/checkout@v6

- name: Install Node.js
id: node
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
node-version-file: ${{ inputs.working-directory }}/.nvmrc

- name: Cache
id: cache
uses: actions/cache@v5
with:
path: ${{ env.CACHE_PATH }}
key: ${{ needs.key.outputs.cache-key }}
- run: corepack enable

- name: Install Depedencies
if: steps.cache.outputs.cache-hit != 'true'
run: |
corepack enable
yarn --immutable
- uses: johngeorgewright/workflows/actions/yarn-cache@main
with:
cache-path: ${{ inputs.cache-path }}
working-directory: ${{ inputs.working-directory }}
36 changes: 27 additions & 9 deletions actions/yarn-cache-key/action.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
name: Yarn Cache Key

author: johngeorgewright
author: DMG Ads

description: Create the Yarn dependency cache key.
description: Create a cache key for you Yarn dependencies

inputs:
working-directory:
description: An optional working directory to discover the cache key
description: Optional directory to execute in
required: false

outputs:
cache-key:
cache-key:
description: The cache key
value: ${{ steps.key.outputs.cache-key }}
cache-restore-keys:
description: Fallback/restore keys
value: ${{ steps.key.outputs.cache-restore-keys }}

runs:
using: composite
steps:
- shell: bash
id: key
- id: key
working-directory: ${{ inputs.working-directory }}
run: |
corepack enable
echo "cache-key=${{ runner.os }}-node-$(node --version)-yarn-$(yarn --version)-${{ hashFiles('**/yarn.lock') }}" >> $GITHUB_OUTPUT
shell: bash
run: | # shell
os='${{ runner.os }}'
node_version=$( node --version )
yarn_version=$( yarn --version )
deps_hash=$(sed -n 's/ resolution: "\(.*\)@npm:.*/\1/p' yarn.lock \
| sort -u \
| sha256sum \
| cut -d ' ' -f 1)

echo "cache-key=deps-${os}-${node_version}-${yarn_version}-${deps_hash}-${{ hashFiles('**/yarn.lock') }}" >> $GITHUB_OUTPUT

echo "cache-restore-keys<<EOF" >> $GITHUB_OUTPUT
echo "deps-${os}-${node_version}-${yarn_version}-${deps_hash}-" >> $GITHUB_OUTPUT
echo "deps-${os}-${node_version}-${yarn_version}-" >> $GITHUB_OUTPUT
echo "deps-${os}-${node_version}-" >> $GITHUB_OUTPUT
echo "deps-${os}-" >> $GITHUB_OUTPUT
echo "deps-" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
44 changes: 37 additions & 7 deletions actions/yarn-cache/action.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: Yarn Cache

author: johngeorgewright
author: DMG Ads

description: Speed up your Node.js builds by caching the Yarn dependencies.

inputs:
cache_path:
cache-path:
description: The cache paths
required: false
default: |
~/.cache
.yarn/unplugged
Expand All @@ -15,19 +16,48 @@ inputs:
description: Optional directory to execute in
required: false

outputs:
cache-key:
description: The cache key
value: ${{ steps.key.outputs.cache-key }}
cache-hit:
description: Whether the cache was used
value: ${{ steps.cache.outputs.cache-hit }}
cache-restore-keys:
description: Fallback/restore keys
value: ${{ steps.key.outputs.cache-restore-keys }}

runs:
using: composite
steps:
- id: key
uses: johngeorgewright/workflows/actions/yarn-cache-key@main
uses: johngeorgewright/workflows/actions/yarn-cache-key@yarn-cache
with:
working-directory: ${{ inputs.working-directory }}

- id: cache
uses: actions/cache@v4
- name: Restore Cache
id: cache
uses: actions/cache/restore@v5
with:
path: ${{ inputs.cache_path }}
key: ${{ steps.key.outputs.cache-key }}
path: ${{ inputs.cache-path }}
restore-keys: ${{ steps.key.outputs.cache-restore-keys }}

- if: steps.cache.outputs.cache-hit != 'true'
- name: Clean Stale Install State
if: steps.cache.outputs.cache-matched-key != '' && steps.cache.outputs.cache-matched-key != steps.key.outputs.cache-key
working-directory: ${{ inputs.working-directory }}
shell: bash
run: rm -f .yarn/install-state.gz

- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
working-directory: ${{ inputs.working-directory }}
shell: bash
run: yarn --immutable

- name: Save Cache
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v5
with:
path: ${{ inputs.cache-path }}
key: ${{ steps.key.outputs.cache-key }}
Loading
Loading