Skip to content

Commit

Permalink
Normalise filter inputs names
Browse files Browse the repository at this point in the history
Resolves #56
Resolves #10

With that change, all filters either start with `keep-` (exclusion) or `prune-` (inclusion).
This contributes to making usage of the action more comprehensible and less error prone.
Non-normalised inputs are preserved for backward compatibility until v2 and/or a minimum of one year.

This change also adds support for multiple regexes via new input `prune-tags-regexes` replacing `tag-regex`.
  • Loading branch information
vlaurin committed Jan 7, 2023
1 parent fd1a465 commit eda6c54
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 55 deletions.
127 changes: 124 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,96 @@ jobs:
- name: Clear node modules
run: rm -rf node_modules/

- name: (Backward compatibility) Should prune untagged versions
uses: ./ # Itself
id: legacy_test_prune_untagged
with:
token: ${{ secrets.GITHUB_TOKEN }}
user: vlaurin
container: test-action-ghcr-prune
dry-run: true
untagged: true
keep-last: 1

- name: (Backward compatibility) Expect 2 untagged versions to be pruned
uses: actions/github-script@v6
with:
script: |
const actualCount = ${{ steps.legacy_test_prune_untagged.outputs.count }};
const expectedCount = 2;
if (actualCount !== expectedCount) {
core.setFailed(`Expected ${expectedCount} versions to be pruned but was: ${actualCount}`)
}
const actualPruned = '${{ steps.legacy_test_prune_untagged.outputs.prunedVersionIds }}';
const expectedPruned = '[15452193,15452086]';
if (actualPruned !== expectedPruned) {
core.setFailed(`Expected ${expectedPruned} to be pruned but was: ${actualPruned}`)
}
- name: (Backward compatibility) Should prune tagged versions without exclusions
uses: ./ # Itself
id: legacy_test_prune_tagged
with:
token: ${{ secrets.GITHUB_TOKEN }}
user: vlaurin
container: test-action-ghcr-prune
dry-run: true
tag-regex: ^pr-
keep-tags: |
pr-demo
- name: (Backward compatibility) Expect 3 tagged versions to be pruned
uses: actions/github-script@v6
with:
script: |
const actualCount = ${{ steps.legacy_test_prune_tagged.outputs.count }};
const expectedCount = 3;
if (actualCount !== expectedCount) {
core.setFailed(`Expected ${expectedCount} versions to be pruned but was: ${actualCount}`)
}
const actualPruned = '${{ steps.legacy_test_prune_tagged.outputs.prunedVersionIds }}';
const expectedPruned = '[15452486,15452460,15452388]';
if (actualPruned !== expectedPruned) {
core.setFailed(`Expected ${expectedPruned} to be pruned but was: ${actualPruned}`)
}
- name: (Backward compatibility) Should prune tagged versions without RegEx exclusions
uses: ./ # Itself
id: legacy_test_prune_tagged_keep_tags_regexes
with:
token: ${{ secrets.GITHUB_TOKEN }}
user: vlaurin
container: test-action-ghcr-prune
dry-run: true
tag-regex: ^pr-
keep-tags-regexes: |
^pr-[a-z]+
^pr-\d\d2
- name: (Backward compatibility) Expect 2 tagged versions to be pruned
uses: actions/github-script@v6
with:
script: |
const actualCount = ${{ steps.legacy_test_prune_tagged_keep_tags_regexes.outputs.count }};
const expectedCount = 2;
if (actualCount !== expectedCount) {
core.setFailed(`Expected ${expectedCount} versions to be pruned but was: ${actualCount}`)
}
const actualPruned = '${{ steps.legacy_test_prune_tagged_keep_tags_regexes.outputs.prunedVersionIds }}';
const expectedPruned = '[15452486,15452388]';
if (actualPruned !== expectedPruned) {
core.setFailed(`Expected ${expectedPruned} to be pruned but was: ${actualPruned}`)
}
- name: Should prune untagged versions
uses: ./ # Itself
id: test_prune_untagged
Expand All @@ -42,7 +132,7 @@ jobs:
user: vlaurin
container: test-action-ghcr-prune
dry-run: true
untagged: true
prune-untagged: true
keep-last: 1

- name: Expect 2 untagged versions to be pruned
Expand Down Expand Up @@ -71,7 +161,7 @@ jobs:
user: vlaurin
container: test-action-ghcr-prune
dry-run: true
tag-regex: ^pr-
prune-tags-regexes: ^pr-
keep-tags: |
pr-demo
Expand Down Expand Up @@ -101,7 +191,7 @@ jobs:
user: vlaurin
container: test-action-ghcr-prune
dry-run: true
tag-regex: ^pr-
prune-tags-regexes: ^pr-
keep-tags-regexes: |
^pr-[a-z]+
^pr-\d\d2
Expand All @@ -123,3 +213,34 @@ jobs:
if (actualPruned !== expectedPruned) {
core.setFailed(`Expected ${expectedPruned} to be pruned but was: ${actualPruned}`)
}
- name: Should prune tagged versions from many regexes
uses: ./ # Itself
id: test_prune_many_tags_regexes
with:
token: ${{ secrets.GITHUB_TOKEN }}
user: vlaurin
container: test-action-ghcr-prune
dry-run: true
prune-tags-regexes: |
^pr-[a-z]+$
^pr-\d{3}$
keep-tags-regexes: 2$

- name: Expect 3 tagged versions to be pruned
uses: actions/github-script@v6
with:
script: |
const actualCount = ${{ steps.test_prune_many_tags_regexes.outputs.count }};
const expectedCount = 3;
if (actualCount !== expectedCount) {
core.setFailed(`Expected ${expectedCount} versions to be pruned but was: ${actualCount}`)
}
const actualPruned = '${{ steps.test_prune_many_tags_regexes.outputs.prunedVersionIds }}';
const expectedPruned = '[15452525,15452486,15452388]';
if (actualPruned !== expectedPruned) {
core.setFailed(`Expected ${expectedPruned} to be pruned but was: ${actualPruned}`)
}
29 changes: 16 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ GitHub Action to prune/delete container versions from GitHub Container Registry

## ⚠️ Word of caution

By default, both `untagged` and `tag-regex` inputs are disabled and as result no versions will be matched for pruning. Either or both inputs must be explicitly configured for versions to be pruned. This behaviour helps to avoid pruning versions by mistake when first configuring this action.
By default, both `prune-untagged` and `prune-tags-regexes` inputs are disabled and as result no versions will be matched for pruning. Either or both inputs must be explicitly configured for versions to be pruned. This behaviour helps to avoid pruning versions by mistake when first configuring this action.

As this action is destructive, it's recommended to test any changes to the configuration of the action with a dry-run to ensure the expected versions are matched for pruning. For more details about dry-runs, see the [dry-run input](#dry-run).

This is especially true when the [`tag-regex` input](#tag-regex) is used as the regular expression can easily match all versions of a container and result in complete deletion of all available versions.
This is especially true when the [`prune-tags-regexes` input](#prune-tags-regexes) is used as regular expressions can easily match all versions of a container and result in complete deletion of all available versions.

## Quick start

Expand All @@ -20,9 +20,9 @@ steps:
organization: your-org
container: your-container
dry-run: true # Dry-run first, then change to `false`
older-than: 7 # days
keep-younger-than: 7 # days
keep-last: 2
untagged: true
prune-untagged: true
```
## Permissions
Expand Down Expand Up @@ -67,10 +67,6 @@ If neither are provided, then the packages of the authenticated user (cf. `token

As this action is destructive, it's recommended to test any changes to the configuration of the action with a dry-run to ensure the expected versions are matched for pruning.

### older-than

**Optional** Minimum age in days of a version before it is pruned. Defaults to `0` which matches all versions of a container.

### keep-last

**Optional** Count of most recent, matching containers to exclude from pruning. Defaults to `0` which means that all matching containers are pruned.
Expand All @@ -86,15 +82,22 @@ Matching is exact and case-sensitive.
**Optional** List of regular expressions for tags to exclude from pruning, one per line.
Each expression will be evaluated against all tags of a version. Any version with at least one tag matching the expression will be excluded from pruning.

### untagged
### keep-younger-than

**Optional** Boolean controlling whether untagged versions should be pruned (`true`) or not (`false`). Defaults to `false`.
**Optional** Minimum age in days a version must have to qualify for pruning. All versions below that age at time of execution are excluded from pruning. Defaults to `0` which means no versions will be excluded from pruning.

### tag-regex
### prune-tags-regexes

**Optional** Regular expression which will be evaluated against all tags of a version. Any version with at least one tag matching the expression will be pruned. Disabled by defaults.
**Optional** List of regular expressions for tags to prune, one per line.
Each expression will be evaluated against all tags of a version.
Any version with at least one tag matching the expression will be pruned.
Disabled by default (ie. no versions pruned based on tags).

:warning: **Please note:** Extra care should be taken when using `tag-regex`, please make sure you've read the [Word of caution](#word-of-caution)
:warning: **Please note:** Extra care should be taken when using `prune-tags-regexes`, please make sure you've read the [Word of caution](#word-of-caution)

### prune-untagged

**Optional** Boolean controlling whether untagged versions should be pruned (`true`) or not (`false`). Defaults to `false`.

## Outputs

Expand Down
14 changes: 14 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ inputs:
Each expression will be evaluated against all tags of a version.
Any version with at least one tag matching the expression will be excluded from pruning.
required: false
keep-younger-than:
description: 'Minimum age in days of container versions that will be pruned'
required: false
default: 0
prune-tags-regexes:
description: |
List of regular expressions for tags to include in pruning, one per line.
Each expression will be evaluated against all tags of a version.
Any version with at least one tag matching the expression will be included in pruning.
required: false
prune-untagged:
description: 'Whether untagged container versions should be pruned'
required: false
default: false
untagged:
description: 'Whether untagged container versions should be pruned'
required: false
Expand Down
10 changes: 7 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,16 @@ const run = async () => {
const dryRun = asBoolean(core.getInput('dry-run'));

const keepLast = Number(core.getInput('keep-last'));

// For backward compatibility of deprecated input `tag-regex`
const legacyTagRegex = core.getInput('tag-regex') ? [core.getInput('tag-regex')] : null;

const filterOptions = {
olderThan: Number(core.getInput('older-than')),
untagged: asBoolean(core.getInput('untagged')),
tagRegex: core.getInput('tag-regex'),
keepTags: core.getMultilineInput('keep-tags'),
keepTagsRegexes: core.getMultilineInput('keep-tags-regexes'),
keepYoungerThan: Number(core.getInput('keep-younger-than')) || Number(core.getInput('older-than')),
pruneTagsRegexes: core.getInput('prune-tags-regexes') ? core.getMultilineInput('prune-tags-regexes') : legacyTagRegex,
pruneUntagged: asBoolean(core.getInput('prune-untagged')) || asBoolean(core.getInput('untagged')),
};

const octokit = github.getOctokit(token);
Expand Down
12 changes: 6 additions & 6 deletions src/version-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ const anyRegexMatch = (regexes) => (tags) =>

const versionFilter = (options) => (version) => {
const {
olderThan,
untagged,
tagRegex,
keepTags,
keepTagsRegexes,
keepYoungerThan,
pruneTagsRegexes,
pruneUntagged,
} = options;
const createdAt = new Date(version.created_at);
const age = daysBetween(createdAt);

if (olderThan > age) {
if (keepYoungerThan > age) {
return false;
}

const tags = version.metadata.container.tags;

if (untagged && (!tags || !tags.length)) {
if (pruneUntagged && (!tags || !tags.length)) {
return true;
}

Expand All @@ -34,7 +34,7 @@ const versionFilter = (options) => (version) => {
return false;
}

if (tagRegex && tags && tags.some((tag) => tag.match(tagRegex))) {
if (pruneTagsRegexes && tags && anyRegexMatch(pruneTagsRegexes)(tags)) {
return true;
}

Expand Down
Loading

0 comments on commit eda6c54

Please sign in to comment.