Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions samples/artifactory/GENERIC_EVENT/archive-old-artifact/README.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be worth adding some Markdown formatting to make this README more readable.
Like for instance this README file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Worker takes a lot of parameters.
Maybe adding few usage examples could make it clearer ?

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Artifactory Archive Old Artifacts User Worker
This worker is used to archive artifacts from a given source repository in Artifactory to a given destination repository. The artifacts are chosen based on a mixture of available parameters.

Note that this worker will delete your artifacts. The archive process is designed to preserve the name, path, and properties of an artifact, but save disk space by deleting the file contents. This worker is to be used for build artifacts that are no longer needed, when it's still useful to keep the build around for auditing or history purposes.


Features
Re-deploys artifacts that are to be archived, to save disk space.
Archived artifacts are moved to an archive repository, to be separate from non-archived artifacts.
Archived artifacts retain all properties that were set, and are also tagged with the archival timestamp.
Input Parameters
filePattern - the file pattern to match against in the source repository
srcRepo - the source repository to scan for artifacts to be archived
archiveRepo - the repository where matching artifacts are archived to
archiveProperty - the name of the property to use when tagging the archived artifact with the archive timestamp
Available 'time period' archive policies:
lastModified - the last time the artifact was modified
lastUpdated - the last time the artifact was updated
created - the creation date of the artifact
lastDownloaded - the last time the artifact was downloaded
age - the age of the artifact
NOTE: the time period archive policies are all specified in number of days

Available 'property' archive policies:
includePropertySet - the artifact will be archived if it possesses all of the passed in properties
excludePropertySet - the artifact will not be archived if it possesses all of the passed in properties
NOTE: property set format ⇒ prop[:value1[;prop2[:value2]......[;propN[:valueN]]])

A property key must be provided, but a corresponding value is not necessary. If a property is set without a value, then a check is made for just the key.

Available artifact keep policy:
numKeepArtifacts - the number of artifacts to keep per directory
NOTE: This allows one to keep X number of artifacts (based on natural directory sort per directory). So, if your artifacts are laid out in a flat directory structure, you can keep the last X artifacts in each directory with this setting.

One can set any number of 'time period' archive policies as well as any number of include and exclude attribute sets. It is up to the caller to decide how best to archive artifacts. If no archive policy parameters are sent in, the plugin aborts in order to not allow default deleting of every artifact.

Archive Process
The 'archive' process performs the following:

Grabs all of the currently set properties on the artifact
Does a deploy over top of the artifact, to conserve space
Adds all of the previously held attributes to the newly deployed artifact
Moves the artifact from the source repository to the destination repository specified
Adds a property containing the archive timestamp to the artifact
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "archive-old-artifact",
"description": "This worker script is designed to archive old artifacts in Artifactory based on configurable criteria. It is useful for managing storage and maintaining repository hygiene.",
"secrets": {},
"sourceCodePath": "./worker.ts",
"action": "GENERIC_EVENT",
"enabled": false,
"debug": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "archive-old-artifact",
"description": "Run a script on GENERIC_EVENT",
"version": "1.0.1",
"scripts": {
"deploy": "jf worker deploy",
"undeploy": "jf worker rm \"archive-old-artifact\"",
"test": "jest"
},
"license": "ISC",
"devDependencies": {
"jfrog-workers": "^0.4.0",
"@golevelup/ts-jest": "^0.4.0",
"@types/jest": "^29.5.12",
"jest": "^29.7.0",
"jest-jasmine2": "^29.7.0",
"ts-jest": "^29.1.2"
},
"jest": {
"moduleFileExtensions": [
"ts",
"js"
],
"rootDir": ".",
"testEnvironment": "node",
"clearMocks": true,
"maxConcurrency": 1,
"testRegex": "\\.spec\\.ts$",
"moduleDirectories": ["node_modules"],
"collectCoverageFrom": [
"**/*.ts"
],
"coverageDirectory": "../coverage",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"testRunner": "jest-jasmine2",
"verbose": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"filePattern": "example.txt",
"srcRepo": "libs-release-local",
"archiveRepo": "archive-repo",
"lastModifiedDays": 30,
"lastUpdatedDays": 0,
"createdDays": 1,
"lastDownloadedDays": 60,
"ageDays": 30,
"excludePropertySet": "keeper:true",
"includePropertySet": "archive:true",
"archiveProperty": "archived.timestamp",
"numKeepArtifacts": 5
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"target": "es2017",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false,
"allowJs": true
},
"include": [
"**/*.ts",
"node_modules/@types/**/*.d.ts"
]
}
37 changes: 37 additions & 0 deletions samples/artifactory/GENERIC_EVENT/archive-old-artifact/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export interface PropertyMap {
[key: string]: string;
}

export interface Checksums {
sha1: string;
md5: string;
sha256: string;
}

export interface Artifact {
repo: string;
path: string;
created: string;
createdBy: string;
lastModified: string;
modifiedBy: string;
lastUpdated: string;
downloadUri: string;
mimeType: string;
size: string;
checksums: Checksums;
originalChecksums: Checksums;
uri: string;
}

export interface ArtifactResponse {
artifact: Artifact;
}

export interface ArtifactStatistics {
uri: string;
downloadCount: number;
lastDownloaded: number;
remoteDownloadCount: number;
remoteLastDownloaded: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { PlatformContext } from 'jfrog-workers';
import archiveOldArtifacts from './worker';

describe('archiveOldArtifacts', () => {
let context: PlatformContext;

beforeEach(() => {
context = {
clients: {
platformHttp: {
get: jest.fn(),
post: jest.fn(),
put: jest.fn(),
},
},
} as unknown as PlatformContext;
});


it('should throw an error when archiveRepo is missing', async () => {
const params = {
filePattern:"example.txt",
srcRepo: "source-repo",
archiveRepo:"",
lastModifiedDays:30,
lastUpdatedDays:80,
createdDays:102,
lastDownloadedDays:20,
ageDays:102,
excludePropertySet: "keeper:true",
includePropertySet: "archive:true",
archiveProperty: "archived.timestamp",
numKeepArtifacts: 5
};

await expect(() => archiveOldArtifacts(context, params)).rejects.toThrow(
'Both srcRepo and archiveRepo must be defined, srcRepo: source-repo, archiveRepo: '
);
});

it('should throw an error when any of the day is missing', async () => {
const params = {
filePattern: "example.txt",
srcRepo: "source-repo",
archiveRepo: "archive-repo",
lastModifiedDays: 0,
lastUpdatedDays: 0,
createdDays: 0,
lastDownloadedDays: 0,
ageDays: 0,
excludePropertySet: "",
includePropertySet: "",
archiveProperty: "archived.timestamp",
numKeepArtifacts: 5
};

await expect(archiveOldArtifacts(context, params)).rejects.toThrow(
'No selection criteria specified!'
);
});


});
Loading