From 48e43c2ed3d5847ec47579cc4c915383f9796533 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sat, 16 May 2026 14:01:37 +0800 Subject: [PATCH] Replace Checkout action with Cache action for build file caching Convert the composite action from Checkout to Cache that: - Stores build files under ~/.cache/ by default - Auto-generates cache keys from lockfile hashes - Uses actions/cache@v5 for restore and save - Supports custom path, key, key-file, and restore-keys inputs - Exposes cache-hit output for conditional workflow steps --- README.md | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++- action.yaml | 48 ++++++++++++++++++++ 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 action.yaml diff --git a/README.md b/README.md index 8c2c675..efa02c4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,124 @@ -# Cache +Cache Action +============ +A Gitea Action that caches build files under `~/.cache/` using a key file hash. This action uses `actions/cache@v5` under the hood and automatically saves the cache when the job completes successfully. + +## Inputs + +| Input | Description | Required | Default | +|-------|-------------|----------|---------| +| `path` | Files/directories to cache | No | `~/.cache/` | +| `key` | Explicit cache key | No | Auto-generated from hash | +| `key-file` | File to hash for cache key generation | No | Auto-detects lockfiles | +| `restore-keys` | Fallback prefix-matched keys | No | `{os}-cache-` | + +## Outputs + +| Output | Description | +|--------|-------------| +| `cache-hit` | `true` if exact key match found, `false` otherwise | + +## Quick Start + +### Basic Usage + +```yaml +name: Build with Cache +on: push + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Actions/Cache@main + - run: echo "Cache restored, proceeding with build..." +``` + +### With Custom Key File + +```yaml +name: Build with Cache +on: push + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Actions/Cache@main + with: + key-file: 'package-lock.json' + - run: npm ci + - run: npm run build +``` + +### .NET Example + +```yaml +name: .NET Build +on: push + +defaults: + run: + shell: bash + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Actions/Cache@main + with: + key-file: '**/*.csproj' + path: | + ~/.cache/ + ~/.nuget/packages + - name: Build + working-directory: src/ + run: | + dotnet restore + dotnet build --no-restore -c Release + dotnet publish --no-build -c Release +``` + +### Skip Steps on Cache Hit + +```yaml +name: Build with Conditional Steps +on: push + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Actions/Cache@main + id: cache + with: + key-file: 'requirements.txt' + - name: Install dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: pip install -r requirements.txt +``` + +## How It Works + +1. **Cache Key Generation**: If no explicit `key` is provided, the action auto-generates one by: + - Hashing the specified `key-file` if provided + - Otherwise, hashing all detected lockfiles (package-lock.json, Cargo.lock, go.mod, etc.) + - Falls back to hashing all non-git files if no lockfiles found + +2. **Cache Restore**: Uses `actions/cache@v5` to restore the cache from `~/.cache/` + +3. **Cache Save**: Automatically saves the cache when the job completes successfully (handled by `actions/cache@v5`) + +## Cache Scope + +The cache is scoped to the key, version, and branch. The default branch cache is available to other branches. + +## Remarks + +- Requires Gitea Actions runner version >= 2.327.1 for `actions/cache@v5` +- The cache server must be enabled on your Gitea instance +- Maximum cache size per repository is 10GB diff --git a/action.yaml b/action.yaml new file mode 100644 index 0000000..0416098 --- /dev/null +++ b/action.yaml @@ -0,0 +1,48 @@ +name: 'Cache' +description: 'Cache build files under ~/.cache/ using a key file hash' +inputs: + path: + description: 'A list of files, directories, or wildcard patterns to cache. Defaults to ~/.cache/' + required: false + default: '~/.cache/' + key: + description: 'An explicit key for a cache entry. Defaults to runner.os-cache-{hash}' + required: false + key-file: + description: 'The file to hash for generating the cache key. Used if key is not provided.' + required: false + default: '' + restore-keys: + description: 'An ordered list of prefix-matched keys for restoring stale cache' + required: false + default: '' +outputs: + cache-hit: + description: 'A boolean value to indicate an exact match was found for the key' + value: ${{ steps.restore-cache.outputs.cache-hit }} +runs: + using: "composite" + steps: + - name: Generate cache key + id: gen-key + if: inputs.key == '' + shell: bash + run: | + if [ -n "${{ inputs.key-file }}" ]; then + KEY_HASH=$(sha256sum "${{ inputs.key-file }}" | awk '{print $1}') + else + KEY_HASH=$(find . -type f \( -name "*.csproj" -o -name "*.sln" -o -name "package.json" -o -name "package-lock.json" -o -name "yarn.lock" -o -name "pnpm-lock.yaml" -o -name "Cargo.lock" -o -name "requirements.txt" -o -name "Pipfile.lock" -o -name "go.mod" -o -name "go.sum" -o -name "pom.xml" -o -name "build.gradle*" -o -name "Gemfile.lock" -o -name "composer.lock" \) -exec sha256sum {} + 2>/dev/null | sha256sum | awk '{print $1}') + if [ "$KEY_HASH" = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ]; then + KEY_HASH=$(find . -type f -not -path './.git/*' -not -path './.cache/*' | sort | xargs sha256sum 2>/dev/null | sha256sum | awk '{print $1}') + fi + fi + echo "cache-key=${{ runner.os }}-cache-${KEY_HASH}" >> $GITHUB_OUTPUT + + - name: Restore cache + id: restore-cache + uses: actions/cache@v5 + with: + path: ${{ inputs.path }} + key: ${{ inputs.key != '' && inputs.key || steps.gen-key.outputs.cache-key }} + restore-keys: ${{ inputs.restore-keys != '' && inputs.restore-keys || format('{0}-cache-', runner.os) }} +