mirror of
https://github.com/github/codeql.git
synced 2025-12-16 08:43:11 +01:00
150 lines
5.6 KiB
YAML
150 lines
5.6 KiB
YAML
name: Cache query compilation
|
|
description: Caches CodeQL compilation caches - should be run both on PRs and pushes to main.
|
|
|
|
inputs:
|
|
key:
|
|
description: 'The cache key to use - should be unique to the workflow'
|
|
required: true
|
|
|
|
outputs:
|
|
cache-dir:
|
|
description: "The directory where the cache was stored"
|
|
value: ${{ steps.output-compilation-dir.outputs.compdir }}
|
|
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
# calculate the merge-base with main, in a way that works both on PRs and pushes to main.
|
|
- name: Calculate merge-base
|
|
shell: bash
|
|
if: ${{ github.event_name == 'pull_request' }}
|
|
env:
|
|
BASE_BRANCH: ${{ github.base_ref }}
|
|
run: |
|
|
MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ")
|
|
echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV
|
|
- name: Restore cache (PR)
|
|
if: ${{ github.event_name == 'pull_request' }}
|
|
uses: actions/cache/restore@v3
|
|
with:
|
|
path: |
|
|
**/.cache
|
|
~/.codeql/compile-cache
|
|
key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }}
|
|
restore-keys: |
|
|
codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }}
|
|
codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-
|
|
codeql-compile-${{ inputs.key }}-main-
|
|
- name: Fill cache (only branch push)
|
|
if: ${{ github.event_name != 'pull_request' }}
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: |
|
|
**/.cache
|
|
~/.codeql/compile-cache
|
|
key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main
|
|
restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation.
|
|
codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-
|
|
codeql-compile-${{ inputs.key }}-main-
|
|
- name: Output-compilationdir
|
|
id: output-compilation-dir
|
|
shell: bash
|
|
run: |
|
|
echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT
|
|
env:
|
|
COMBINED_CACHE_DIR: ${{ runner.temp }}/compilation-dir
|
|
- name: Fill compilation cache directory
|
|
id: fill-compilation-dir
|
|
uses: actions/github-script@v6
|
|
env:
|
|
COMBINED_CACHE_DIR: ${{ runner.temp }}/compilation-dir
|
|
with:
|
|
script: |
|
|
// # Move all the existing cache into another folder, so we only preserve the cache for the current queries.
|
|
// mkdir -p ${COMBINED_CACHE_DIR}
|
|
// rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty.
|
|
// # copy the contents of the .cache folders into the combined cache folder.
|
|
// cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files
|
|
// # clean up the .cache folders
|
|
// rm -rf **/.cache/*
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const os = require("os");
|
|
|
|
// the first argv is the cache folder to create.
|
|
const COMBINED_CACHE_DIR = process.env.COMBINED_CACHE_DIR;
|
|
|
|
function* walkCaches(dir) {
|
|
const files = fs.readdirSync(dir, { withFileTypes: true });
|
|
for (const file of files) {
|
|
if (file.isDirectory()) {
|
|
const filePath = path.join(dir, file.name);
|
|
yield* walkCaches(filePath);
|
|
if (file.name === ".cache") {
|
|
yield filePath;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function copyDir(src, dest) {
|
|
for await (const file of await fs.promises.readdir(src, { withFileTypes: true })) {
|
|
const srcPath = path.join(src, file.name);
|
|
const destPath = path.join(dest, file.name);
|
|
if (file.isDirectory()) {
|
|
if (!fs.existsSync(destPath)) {
|
|
fs.mkdirSync(destPath);
|
|
}
|
|
await copyDir(srcPath, destPath);
|
|
} else {
|
|
await fs.promises.copyFile(srcPath, destPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const cacheDirs = [...walkCaches(".")];
|
|
|
|
for (const dir of cacheDirs) {
|
|
console.log(`Found .cache dir at ${dir}`);
|
|
}
|
|
|
|
const globalCacheDir = path.join(os.homedir(), ".codeql", "compile-cache");
|
|
if (fs.existsSync(globalCacheDir)) {
|
|
console.log("Found global home dir: " + globalCacheDir);
|
|
cacheDirs.push(globalCacheDir);
|
|
}
|
|
|
|
if (cacheDirs.length === 0) {
|
|
console.log("No cache dirs found");
|
|
return;
|
|
}
|
|
|
|
// mkdir -p ${COMBINED_CACHE_DIR}
|
|
fs.mkdirSync(COMBINED_CACHE_DIR, { recursive: true });
|
|
|
|
// rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty.
|
|
await Promise.all(
|
|
cacheDirs.map((cacheDir) =>
|
|
(async function () {
|
|
await fs.promises.rm(path.join(cacheDir, "lock"), { force: true });
|
|
await fs.promises.rm(path.join(cacheDir, "size"), { force: true });
|
|
})()
|
|
)
|
|
);
|
|
|
|
// # copy the contents of the .cache folders into the combined cache folder.
|
|
// cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files
|
|
await Promise.all(
|
|
cacheDirs.map((cacheDir) => copyDir(cacheDir, COMBINED_CACHE_DIR))
|
|
);
|
|
|
|
// # clean up the .cache folders
|
|
// rm -rf **/.cache/*
|
|
await Promise.all(
|
|
cacheDirs.map((cacheDir) => fs.promises.rm(cacheDir, { recursive: true }))
|
|
);
|
|
}
|
|
main();
|