Add cache prefix support
This commit is contained in:
parent
3f3b0175e8
commit
ee531bffac
|
@ -19,6 +19,7 @@ This can be achieved with the following [configuration in the action](https://do
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
permissions:
|
permissions:
|
||||||
|
actions: write # for caching state
|
||||||
contents: write # only for delete-branch option
|
contents: write # only for delete-branch option
|
||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
@ -97,6 +98,7 @@ Every argument is optional.
|
||||||
| [ignore-issue-updates](#ignore-issue-updates) | Override [ignore-updates](#ignore-updates) for issues only | |
|
| [ignore-issue-updates](#ignore-issue-updates) | Override [ignore-updates](#ignore-updates) for issues only | |
|
||||||
| [ignore-pr-updates](#ignore-pr-updates) | Override [ignore-updates](#ignore-updates) for PRs only | |
|
| [ignore-pr-updates](#ignore-pr-updates) | Override [ignore-updates](#ignore-updates) for PRs only | |
|
||||||
| [include-only-assigned](#include-only-assigned) | Process only assigned issues | `false` |
|
| [include-only-assigned](#include-only-assigned) | Process only assigned issues | `false` |
|
||||||
|
| [cache-prefix](#cache-prefix) | Add a prefix to the stored cache | |
|
||||||
|
|
||||||
### List of output options
|
### List of output options
|
||||||
|
|
||||||
|
@ -547,6 +549,11 @@ If set to `true`, only the issues or the pull requests with an assignee will be
|
||||||
|
|
||||||
Default value: `false`
|
Default value: `false`
|
||||||
|
|
||||||
|
#### cache-prefix
|
||||||
|
|
||||||
|
Beneficial so the action has a more unique cahce key. Useful when calling this action multiple times, independent of each other.
|
||||||
|
An example for usage would be closing all PRs with `x` label after 7 days in one action and closing all PRs except for `x` label after 10 days in another.
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
See also [action.yml](./action.yml) for a comprehensive list of all the options.
|
See also [action.yml](./action.yml) for a comprehensive list of all the options.
|
||||||
|
|
|
@ -55,5 +55,6 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({
|
||||||
ignorePrUpdates: undefined,
|
ignorePrUpdates: undefined,
|
||||||
exemptDraftPr: false,
|
exemptDraftPr: false,
|
||||||
closeIssueReason: 'not_planned',
|
closeIssueReason: 'not_planned',
|
||||||
includeOnlyAssigned: false
|
includeOnlyAssigned: false,
|
||||||
|
cachePrefix: ''
|
||||||
});
|
});
|
||||||
|
|
|
@ -204,6 +204,10 @@ inputs:
|
||||||
description: 'Only the issues or the pull requests with an assignee will be marked as stale automatically.'
|
description: 'Only the issues or the pull requests with an assignee will be marked as stale automatically.'
|
||||||
default: 'false'
|
default: 'false'
|
||||||
required: false
|
required: false
|
||||||
|
cache-prefix:
|
||||||
|
description: 'Add a prefix to the stored cache. Useful when using this action multiple times with different params.'
|
||||||
|
default: ''
|
||||||
|
required: false
|
||||||
outputs:
|
outputs:
|
||||||
closed-issues-prs:
|
closed-issues-prs:
|
||||||
description: 'List of all closed issues and pull requests.'
|
description: 'List of all closed issues and pull requests.'
|
||||||
|
|
|
@ -64,7 +64,8 @@ describe('Issue', (): void => {
|
||||||
ignorePrUpdates: undefined,
|
ignorePrUpdates: undefined,
|
||||||
exemptDraftPr: false,
|
exemptDraftPr: false,
|
||||||
closeIssueReason: '',
|
closeIssueReason: '',
|
||||||
includeOnlyAssigned: false
|
includeOnlyAssigned: false,
|
||||||
|
cachePrefix: ''
|
||||||
};
|
};
|
||||||
issueInterface = {
|
issueInterface = {
|
||||||
title: 'dummy-title',
|
title: 'dummy-title',
|
||||||
|
|
|
@ -6,6 +6,7 @@ import * as core from '@actions/core';
|
||||||
import {context, getOctokit} from '@actions/github';
|
import {context, getOctokit} from '@actions/github';
|
||||||
import {retry as octokitRetry} from '@octokit/plugin-retry';
|
import {retry as octokitRetry} from '@octokit/plugin-retry';
|
||||||
import * as cache from '@actions/cache';
|
import * as cache from '@actions/cache';
|
||||||
|
import {IIssuesProcessorOptions} from '../../interfaces/issues-processor-options';
|
||||||
|
|
||||||
const CACHE_KEY = '_state';
|
const CACHE_KEY = '_state';
|
||||||
const STATE_FILE = 'state.txt';
|
const STATE_FILE = 'state.txt';
|
||||||
|
@ -65,15 +66,26 @@ const resetCacheWithOctokit = async (cacheKey: string): Promise<void> => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export class StateCacheStorage implements IStateStorage {
|
export class StateCacheStorage implements IStateStorage {
|
||||||
|
/**
|
||||||
|
* @private don't mutate in the debug mode
|
||||||
|
*/
|
||||||
|
private readonly statePrefix: string;
|
||||||
|
|
||||||
|
constructor(options: IIssuesProcessorOptions) {
|
||||||
|
this.statePrefix = options.cachePrefix;
|
||||||
|
}
|
||||||
|
|
||||||
async save(serializedState: string): Promise<void> {
|
async save(serializedState: string): Promise<void> {
|
||||||
const tmpDir = mkTempDir();
|
const tmpDir = mkTempDir();
|
||||||
const filePath = path.join(tmpDir, STATE_FILE);
|
const stateFile = `${this.statePrefix}_${STATE_FILE}`;
|
||||||
|
const filePath = path.join(tmpDir, stateFile);
|
||||||
fs.writeFileSync(filePath, serializedState);
|
fs.writeFileSync(filePath, serializedState);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cacheExists = await checkIfCacheExists(CACHE_KEY);
|
const cacheKey = `${this.statePrefix}${CACHE_KEY}`;
|
||||||
|
const cacheExists = await checkIfCacheExists(cacheKey);
|
||||||
if (cacheExists) {
|
if (cacheExists) {
|
||||||
await resetCacheWithOctokit(CACHE_KEY);
|
await resetCacheWithOctokit(cacheKey);
|
||||||
}
|
}
|
||||||
const fileSize = fs.statSync(filePath).size;
|
const fileSize = fs.statSync(filePath).size;
|
||||||
|
|
||||||
|
@ -82,7 +94,7 @@ export class StateCacheStorage implements IStateStorage {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await cache.saveCache([path.dirname(filePath)], CACHE_KEY);
|
await cache.saveCache([path.dirname(filePath)], cacheKey);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(
|
core.warning(
|
||||||
`Saving the state was not successful due to "${
|
`Saving the state was not successful due to "${
|
||||||
|
@ -96,10 +108,12 @@ export class StateCacheStorage implements IStateStorage {
|
||||||
|
|
||||||
async restore(): Promise<string> {
|
async restore(): Promise<string> {
|
||||||
const tmpDir = mkTempDir();
|
const tmpDir = mkTempDir();
|
||||||
const filePath = path.join(tmpDir, STATE_FILE);
|
const stateFile = `${this.statePrefix}_${STATE_FILE}`;
|
||||||
|
const filePath = path.join(tmpDir, stateFile);
|
||||||
unlinkSafely(filePath);
|
unlinkSafely(filePath);
|
||||||
try {
|
try {
|
||||||
const cacheExists = await checkIfCacheExists(CACHE_KEY);
|
const cacheKey = `${this.statePrefix}${CACHE_KEY}`;
|
||||||
|
const cacheExists = await checkIfCacheExists(cacheKey);
|
||||||
if (!cacheExists) {
|
if (!cacheExists) {
|
||||||
core.info(
|
core.info(
|
||||||
'The saved state was not found, the process starts from the first issue.'
|
'The saved state was not found, the process starts from the first issue.'
|
||||||
|
@ -107,7 +121,7 @@ export class StateCacheStorage implements IStateStorage {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
await cache.restoreCache([path.dirname(filePath)], CACHE_KEY);
|
await cache.restoreCache([path.dirname(filePath)], cacheKey);
|
||||||
|
|
||||||
if (!fs.existsSync(filePath)) {
|
if (!fs.existsSync(filePath)) {
|
||||||
core.warning(
|
core.warning(
|
||||||
|
@ -115,7 +129,7 @@ export class StateCacheStorage implements IStateStorage {
|
||||||
);
|
);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return fs.readFileSync(path.join(tmpDir, STATE_FILE), {
|
return fs.readFileSync(path.join(tmpDir, stateFile), {
|
||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -48,5 +48,6 @@ export enum Option {
|
||||||
IgnoreIssueUpdates = 'ignore-issue-updates',
|
IgnoreIssueUpdates = 'ignore-issue-updates',
|
||||||
IgnorePrUpdates = 'ignore-pr-updates',
|
IgnorePrUpdates = 'ignore-pr-updates',
|
||||||
ExemptDraftPr = 'exempt-draft-pr',
|
ExemptDraftPr = 'exempt-draft-pr',
|
||||||
CloseIssueReason = 'close-issue-reason'
|
CloseIssueReason = 'close-issue-reason',
|
||||||
|
CachePrefix = 'cache-prefix'
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,4 +54,5 @@ export interface IIssuesProcessorOptions {
|
||||||
exemptDraftPr: boolean;
|
exemptDraftPr: boolean;
|
||||||
closeIssueReason: string;
|
closeIssueReason: string;
|
||||||
includeOnlyAssigned: boolean;
|
includeOnlyAssigned: boolean;
|
||||||
|
cachePrefix: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,8 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
|
||||||
ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'),
|
ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'),
|
||||||
exemptDraftPr: core.getInput('exempt-draft-pr') === 'true',
|
exemptDraftPr: core.getInput('exempt-draft-pr') === 'true',
|
||||||
closeIssueReason: core.getInput('close-issue-reason'),
|
closeIssueReason: core.getInput('close-issue-reason'),
|
||||||
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true'
|
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true',
|
||||||
|
cachePrefix: core.getInput('cache-prefix')
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const numberInput of ['days-before-stale']) {
|
for (const numberInput of ['days-before-stale']) {
|
||||||
|
|
|
@ -4,6 +4,6 @@ import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
|
||||||
import {StateCacheStorage} from '../classes/state/state-cache-storage';
|
import {StateCacheStorage} from '../classes/state/state-cache-storage';
|
||||||
|
|
||||||
export const getStateInstance = (options: IIssuesProcessorOptions): IState => {
|
export const getStateInstance = (options: IIssuesProcessorOptions): IState => {
|
||||||
const storage = new StateCacheStorage();
|
const storage = new StateCacheStorage(options);
|
||||||
return new State(storage, options);
|
return new State(storage, options);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue