From 49545e26e4657120792a0f5dc69e90f8df2b376c Mon Sep 17 00:00:00 2001 From: JuanGalilea Date: Wed, 8 Apr 2026 09:26:38 +0200 Subject: [PATCH] feat(github-actions): add caching for dependencies and bump to node 24 prettier formatting base caching job cache restore composite action cache and restore using job and composite checkout before? wtf? remove comments and extra checkout version bumps out the ass fix working directory package-lock reference additional working directory for amazon ??????????? lockstep with apify-store --- .../checkout-restore-dependencies/action.yaml | 35 +++++ .github/workflows/cache-dependencies.yaml | 46 ++++++ .github/workflows/platform-tests.yaml | 8 +- .github/workflows/pr-build-test.yaml | 143 ++++++++++-------- .github/workflows/push-build-latest.yaml | 12 +- 5 files changed, 169 insertions(+), 75 deletions(-) create mode 100644 .github/actions/checkout-restore-dependencies/action.yaml create mode 100644 .github/workflows/cache-dependencies.yaml diff --git a/.github/actions/checkout-restore-dependencies/action.yaml b/.github/actions/checkout-restore-dependencies/action.yaml new file mode 100644 index 0000000..f7dbb78 --- /dev/null +++ b/.github/actions/checkout-restore-dependencies/action.yaml @@ -0,0 +1,35 @@ +name: Checkout and restore dependencies +description: Checkout and restore dependencies +inputs: + working-directory: + description: Working directory + required: false + default: . + additional-working-directory: + type: string + required: false + +runs: + using: "composite" + steps: + - id: checkout + uses: actions/checkout@v5 + + - name: Load cached dependencies + id: restore-dependency-cache + uses: actions/cache/restore@v5 + with: + fail-on-cache-miss: true + path: ${{ inputs.working-directory }}/node_modules + key: modules-npm-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/package-lock.json', inputs.working-directory)) }} + + # Some repos require additional dependencies to be cached + # like amazon having its actor under ./code and some extra stuff under ./amazon-ts + - name: Load additional cached dependencies + id: restore-additional-dependency-cache + if: inputs.additional-working-directory != '' + uses: actions/cache/restore@v5 + with: + fail-on-cache-miss: true + path: ${{ inputs.additional-working-directory }}/node_modules + key: modules-npm-${{ inputs.additional-working-directory }}-${{ hashFiles(format('{0}/package-lock.json', inputs.additional-working-directory)) }} diff --git a/.github/workflows/cache-dependencies.yaml b/.github/workflows/cache-dependencies.yaml new file mode 100644 index 0000000..1ad476f --- /dev/null +++ b/.github/workflows/cache-dependencies.yaml @@ -0,0 +1,46 @@ +name: Cache Dependencies + +on: + workflow_call: + inputs: + working-directory: + type: string + default: . + required: false + additional-working-directory: + type: string + required: false + +jobs: + cache-dependencies: + name: Cache Dependencies + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + - name: Cache dependencies npm + id: check-dependencies-cache + uses: actions/cache@v5 + with: + path: ${{ inputs.working-directory }}/node_modules + key: modules-npm-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/package-lock.json', inputs.working-directory)) }} + + - name: Cache additional dependencies npm + if: inputs.additional-working-directory != '' + id: check-additional-dependencies-cache + uses: actions/cache@v5 + with: + path: ${{ inputs.additional-working-directory }}/node_modules + key: modules-npm-${{ inputs.additional-working-directory }}-${{ hashFiles(format('{0}/package-lock.json', inputs.additional-working-directory)) }} + + - name: install npm dependencies + if: steps.check-dependencies-cache.outputs.cache-hit != 'true' + run: | + cd ${{ inputs.working-directory }} + npm ci + + - name: install additional npm dependencies + if: steps.check-additional-dependencies-cache.outputs.cache-hit != 'true' + run: | + cd ${{ inputs.additional-working-directory }} + npm ci diff --git a/.github/workflows/platform-tests.yaml b/.github/workflows/platform-tests.yaml index 7745528..3fb2ec9 100644 --- a/.github/workflows/platform-tests.yaml +++ b/.github/workflows/platform-tests.yaml @@ -22,13 +22,13 @@ jobs: working-directory: ${{ inputs.working-directory }} steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: - fetch-depth: 0 + fetch-depth: 0 - uses: oNaiPs/secrets-to-env-action@b64e0192bc4bd2ec0682dee8696470d4866577fa with: - secrets: ${{ toJSON(secrets) }} + secrets: ${{ toJSON(secrets) }} - name: Install dependencies run: npm install @@ -70,4 +70,4 @@ jobs: if: always() with: name: vitest-results - path: ./test-output.json \ No newline at end of file + path: ./test-output.json diff --git a/.github/workflows/pr-build-test.yaml b/.github/workflows/pr-build-test.yaml index 048c3de..711132e 100644 --- a/.github/workflows/pr-build-test.yaml +++ b/.github/workflows/pr-build-test.yaml @@ -7,6 +7,9 @@ on: type: string default: . required: false + additional-working-directory: + type: string + required: false skip-platform-tests: type: boolean default: false @@ -17,6 +20,11 @@ concurrency: cancel-in-progress: true jobs: + cache-dependencies: + uses: ./.github/workflows/cache-dependencies.yaml + with: + working-directory: ${{ inputs.working-directory }} + additional-working-directory: ${{ inputs.additional-working-directory }} checkTestFolder: if: ${{ !inputs.skip-platform-tests }} @@ -24,17 +32,17 @@ jobs: defaults: run: working-directory: ${{ inputs.working-directory }} - + steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Check for test folder id: check run: | - if [ ! -d "test/platform" ]; then - echo "No platform test folder found. Failing the workflow." - exit 1 - fi + if [ ! -d "test/platform" ]; then + echo "No platform test folder found. Failing the workflow." + exit 1 + fi platformTest: if: ${{ !inputs.skip-platform-tests }} @@ -45,27 +53,35 @@ jobs: working-directory: ${{ inputs.working-directory }} steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: - fetch-depth: 0 + fetch-depth: 0 + # A simple node script that converts secrets to env vars + # Use specific commit SHA to prevent someone stealing that repo + # - Useful for passing dynamic secrets to env variables, e.g. NPM_TOKEN to `npm ci` step - uses: oNaiPs/secrets-to-env-action@b64e0192bc4bd2ec0682dee8696470d4866577fa with: - secrets: ${{ toJSON(secrets) }} + secrets: ${{ toJSON(secrets) }} - name: Pick last validated commit from cache id: base_commit - uses: actions/cache@v4 + uses: actions/cache@v5 + with: + # We have to call it base commit for the library but it makes more sense as "last validated commit" + # Using run_id ensures the key is always unique so the cache always saves at end-of-job (no "cache hit, not saving" issue) + path: ./base_commit.txt + key: base_commit-${{ github.run_id }} + # This is needed to force overriding the cache with new entry at the end + restore-keys: base_commit- + + - name: Use Node.js 24 + uses: actions/setup-node@v4 with: - # We have to call it base commit for the library but it makes more sense as "last validated commit" - # Using run_id ensures the key is always unique so the cache always saves at end-of-job (no "cache hit, not saving" issue) - path: ./base_commit.txt - key: base_commit-${{ github.run_id }} - # This is needed to force overriding the cache with new entry at the end - restore-keys: base_commit- + node-version: 24 - name: Install dependencies - run: npm install + run: npm ci # Repos can still have older version locally but on cloud we enforce uniformity - name: Enforce latest test tools version @@ -109,56 +125,53 @@ jobs: unitTest: # TODO: only run on changes to code runs-on: ubuntu-latest + needs: cache-dependencies defaults: run: working-directory: ${{ inputs.working-directory }} steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Use Node.js 20 - uses: actions/setup-node@v3 - with: - node-version: 20 - cache: 'npm' - cache-dependency-path: ${{ inputs.working-directory }} # https://github.com/actions/setup-node/issues/706 - - name: Install Dependencies - run: npm ci - - - name: TypeScript - # Some repos require custom build checks, so we check if the `build-check` script exists and run it if - # it does. Otherwise default to the standard `npx tsc --noEmit` check - run: | - HAS_CUSTOM_BUILD_CHECK=$(npx -y json -f package.json scripts.build-check) - if [ -z "$HAS_CUSTOM_BUILD_CHECK" ]; then - npx tsc --noEmit; - else - npm run build-check; - fi - - - name: Lint - run: npm run lint - - - name: Test - run: npm test - - - name: Prettier Check - run: | - if [ -d "node_modules/prettier" ]; then - npx prettier --check .; - else - echo "Prettier is not installed. Skipping Prettier check."; - fi - - - name: Unused Exports Check - run: | - if [ -d "node_modules/knip" ]; then - echo "Knip is installed. Running knip to check for unused exports."; - npx knip --include exports,types; - elif [ -d "node_modules/ts-unused-exports" ]; then - echo "Knip is not installed, but ts-unused-exports is. Running ts-unused-exports to check for unused exports."; - npx ts-unused-exports ./tsconfig.json; - else - echo "knip nor ts-unused-exports are installed. Skipping unused exports check."; - fi + - name: Setup repository and dependencies + # Referenced globally, local reference failed when looking for the action in the consumer repo + # it was being looked for within the repo, not as a relative path to this job when invoked + uses: apify-projects/github-actions-source/.github/actions/checkout-restore-dependencies@master + with: + working-directory: ${{ inputs.working-directory }} + additional-working-directory: ${{ inputs.additional-working-directory }} + + - name: TypeScript + # Some repos require custom build checks, so we check if the `build-check` script exists and run it if + # it does. Otherwise default to the standard `npx tsc --noEmit` check + run: | + HAS_CUSTOM_BUILD_CHECK=$(jq -r '.scripts["build-check"] // empty' package.json) + if [ -z "$HAS_CUSTOM_BUILD_CHECK" ]; then + npx tsc --noEmit; + else + npm run build-check; + fi + + - name: Lint + run: npm run lint + + - name: Test + run: npm test + + - name: Prettier Check + run: | + if [ -d "node_modules/prettier" ]; then + npx prettier --check .; + else + echo "Prettier is not installed. Skipping Prettier check."; + fi + + - name: Unused Exports Check + run: | + if [ -d "node_modules/knip" ]; then + echo "Knip is installed. Running knip to check for unused exports."; + npx knip --include exports,types; + elif [ -d "node_modules/ts-unused-exports" ]; then + echo "Knip is not installed, but ts-unused-exports is. Running ts-unused-exports to check for unused exports."; + npx ts-unused-exports ./tsconfig.json; + else + echo "knip nor ts-unused-exports are installed. Skipping unused exports check."; + fi diff --git a/.github/workflows/push-build-latest.yaml b/.github/workflows/push-build-latest.yaml index 23bc2ec..0ad38b9 100644 --- a/.github/workflows/push-build-latest.yaml +++ b/.github/workflows/push-build-latest.yaml @@ -10,10 +10,10 @@ on: jobs: pushBuildLatest: - name: 'Build latest: ${{github.repository}} ${{github.event.head_commit.message}}' + name: "Build latest: ${{github.repository}} ${{github.event.head_commit.message}}" if: | - !contains(github.event.head_commit.message, '[skip ci]') && - !contains(github.event.head_commit.message, '[skip platform-test]') + !contains(github.event.head_commit.message, '[skip ci]') && + !contains(github.event.head_commit.message, '[skip platform-test]') runs-on: ubuntu-latest defaults: @@ -21,14 +21,14 @@ jobs: working-directory: ${{ inputs.working-directory }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: - fetch-depth: 0 + fetch-depth: 0 # A simple node script that converts secrets to env vars # Use specific commit SHA to prevent someone stealing that repo - uses: oNaiPs/secrets-to-env-action@b64e0192bc4bd2ec0682dee8696470d4866577fa with: - secrets: ${{ toJSON(secrets) }} + secrets: ${{ toJSON(secrets) }} - name: Install dependencies run: npm install