Skip to content

Commit 40875f8

Browse files
committed
fixed prune date range calculation
1 parent 78e847c commit 40875f8

File tree

6 files changed

+215
-161
lines changed

6 files changed

+215
-161
lines changed

docs/development.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ If you want to develop Linux on Windows, Vagrant is an excellent and convenient
1616
- Dotnet 6.0 SDK
1717
- Visual Studio 2019 (Windows) or Visual Studio Code with C# extension. If you're using Visual Studio make sure you've update to the latest version. Visual Studio 2017 isn't supported.
1818

19+
Unit test coverage is done with https://github.com/SteveGilham/altcover, install ReportGenerator with
20+
21+
dotnet tool install --global dotnet-reportgenerator-globaltool
22+
1923
## Running from Visual Studio
2024

2125
- Start Visual Studio as administrator
@@ -73,15 +77,10 @@ To run tests in Visual Studio, open Test > Windows > Test Explorer, run desired
7377

7478
## Test coverage reports
7579

76-
Unit test coverage is done with https://github.com/SteveGilham/altcover. To visualize your tests
77-
78-
- Install ReportGenerator
79-
80-
dotnet tool install --global dotnet-reportgenerator-globaltool
81-
82-
- after testing run
80+
After testing run
8381

8482
cd /src
83+
8584
reportgenerator -reports:./Tetrifact.Tests/coverage.xml -targetdir:./Tetrifact.Tests/coverage -assemblyfilters:+Tetrifact.*;-Tetrifact.Tests -classfilters:-Tetrifact.Core.ThreadDefault;-Tetrifact.Web.DaemonProcessRunner;-Tetrifact.Web.Pager;-Tetrifact.Web.Program;-Tetrifact.Web.Startup;-Tetrifact.Web.ReadLevel;-Tetrifact.Web.WriteLevel;-*f__*
8685

8786
The HTML report is at

docs/use.md

+158-123
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,158 @@
1-
# Using Tetrifact
2-
3-
Tetrifact stores builds as packages. A package is a group of files which are added and retrieved as a unit, and should correspond to a single build in your CI system, which in turn should of course correspond to a COMMIT or REVISION in your VCS (version control system). It is highly recommended you name your Tetrifact packages after the revision number (or hash) in your VCS the package's contents were compiled from, as this allows you to easily trace a package back to the source code from which it was built.
4-
5-
Don't worry if your revision hashes are difficult to pass around, share or remember, packages can be tagged with additional human-friendly names too.
6-
7-
## Changing log level
8-
9-
The default log level as of version 1.8.4 is `Warning`. You can override this with the environment variable
10-
11-
Logging__LogLevel__Microsoft=<YOUR LEVEL>
12-
13-
Allowed levels are the standard internal Dotnet values : Trace|Debug|Information|Warning|Error|Critical|None
14-
15-
## REST
16-
17-
All Tetrifact's functionality is exposed via a REST API, so it should be familiar.
18-
19-
## Adding a package
20-
21-
### As individual files
22-
23-
HTTP METHOD :
24-
25-
POST
26-
27-
ENDPOINT :
28-
29-
/v1/packages/myPackageName
30-
31-
HEADER :
32-
33-
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
34-
35-
BODY :
36-
37-
---------------------------acebdf13572468
38-
Content-Disposition: form-data; name="Files"; filename="1.txt"
39-
40-
file 1 text or binary content here
41-
---------------------------acebdf13572468
42-
Content-Disposition: form-data; name="Files" ; filename="path/to/2.txt"
43-
44-
file 2 text or binary content here
45-
---------------------------acebdf13572468
46-
47-
Each file's "name" property must be "Files". The filename property should be the path and filename of the file you want to store, relative to the root of the package.
48-
49-
Were you posting actual files with CURL it should look like
50-
51-
curl -X POST \
52-
-H "Content-Type: multipart/form-data" \
53-
-H "Transfer-Encoding: chunked" \
54-
-F "Files=@~/mybuild/1.txt;filename=1.txt" \
55-
-F "Files=@~/mybuild/path/to/2.txt;filename=path/to/2.txt" \
56-
http://myTetrifact.server/v1/packages/myPackageName
57-
58-
### As an archive
59-
60-
To post your build as an archive, use the following.
61-
62-
HTTP METHOD :
63-
64-
POST
65-
66-
ENDPOINT :
67-
68-
/v1/packages/myPackageName?IsArchive=true
69-
70-
HEADER :
71-
72-
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
73-
74-
BODY :
75-
76-
---------------------------acebdf13572468
77-
Content-Disposition: form-data; name="FILES"; filename="whatever"
78-
Content-Type: application/octet-stream
79-
80-
<@INCLUDE *~/path/to/archive.zip*@>
81-
---------------------------acebdf13572468
82-
83-
When posting a zip, note the following
84-
85-
- only a single file can be attached to your post. If you add more than one, you'll get an error.
86-
- filename doesn't matter, as it won't be used
87-
- the archive's root will be treated as the root of the project, meaning all file paths will be mapped relative to this.
88-
89-
With CURL it would look like
90-
91-
curl -X POST -H "Content-Type: multipart/form-data" -H "Transfer-Encoding: chunked" -F "Files=@path/to/archive" http://tetriserver.example.com/v1/packages/myPackage?isArchive=true
92-
93-
Chunking the upload is important if your archive is large, as this might exceeded the multipart body attachment size.
94-
95-
### Posting an archive from NodeJS
96-
97-
This uses the request package (https://www.npmjs.com/package/request).
98-
99-
let request = require('request'),
100-
fs = require('fs'),
101-
formdata = {
102-
Files : fs.createReadStream('path/to/archive')
103-
};
104-
105-
request.post({url: 'http://tetriserver.example.com', formData: formdata}, function(err, httpResponse, body) {
106-
if (err) {
107-
return console.error('upload failed : ', err);
108-
}
109-
110-
console.log('Upload succeeded : ', body);
111-
});
112-
113-
## Tagging
114-
115-
### Curl
116-
117-
To add the tag "MyTag" to the package "MyPackage, use
118-
119-
curl -X POST http://tetriserver.example.com/v1/tags/MyTag/MyPackage
120-
121-
To remove the tag
122-
123-
curl -X DELETE http://tetriserver.example.com/v1/tags/MyTag/MyPackage
1+
# Using Tetrifact
2+
3+
Tetrifact stores builds as packages. A package is a group of files which are added and retrieved as a unit, and should correspond to a single build in your CI system, which in turn should of course correspond to a COMMIT or REVISION in your VCS (version control system). It is highly recommended you name your Tetrifact packages after the revision number (or hash) in your VCS the package's contents were compiled from, as this allows you to easily trace a package back to the source code from which it was built.
4+
5+
Don't worry if your revision hashes are difficult to pass around, share or remember, packages can be tagged with additional human-friendly names too.
6+
7+
## Changing log level
8+
9+
The default log level as of version 1.8.4 is `Warning`. You can override this with the environment variable
10+
11+
Logging__LogLevel__Microsoft=<YOUR LEVEL>
12+
13+
Allowed levels are the standard internal Dotnet values : Trace|Debug|Information|Warning|Error|Critical|None
14+
15+
## REST
16+
17+
All Tetrifact's functionality is exposed via a REST API, so it should be familiar.
18+
19+
## Adding a package
20+
21+
### As individual files
22+
23+
HTTP METHOD :
24+
25+
POST
26+
27+
ENDPOINT :
28+
29+
/v1/packages/myPackageName
30+
31+
HEADER :
32+
33+
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
34+
35+
BODY :
36+
37+
---------------------------acebdf13572468
38+
Content-Disposition: form-data; name="Files"; filename="1.txt"
39+
40+
file 1 text or binary content here
41+
---------------------------acebdf13572468
42+
Content-Disposition: form-data; name="Files" ; filename="path/to/2.txt"
43+
44+
file 2 text or binary content here
45+
---------------------------acebdf13572468
46+
47+
Each file's "name" property must be "Files". The filename property should be the path and filename of the file you want to store, relative to the root of the package.
48+
49+
Were you posting actual files with CURL it should look like
50+
51+
curl -X POST \
52+
-H "Content-Type: multipart/form-data" \
53+
-H "Transfer-Encoding: chunked" \
54+
-F "Files=@~/mybuild/1.txt;filename=1.txt" \
55+
-F "Files=@~/mybuild/path/to/2.txt;filename=path/to/2.txt" \
56+
http://myTetrifact.server/v1/packages/myPackageName
57+
58+
### As an archive
59+
60+
To post your build as an archive, use the following.
61+
62+
HTTP METHOD :
63+
64+
POST
65+
66+
ENDPOINT :
67+
68+
/v1/packages/myPackageName?IsArchive=true
69+
70+
HEADER :
71+
72+
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
73+
74+
BODY :
75+
76+
---------------------------acebdf13572468
77+
Content-Disposition: form-data; name="FILES"; filename="whatever"
78+
Content-Type: application/octet-stream
79+
80+
<@INCLUDE *~/path/to/archive.zip*@>
81+
---------------------------acebdf13572468
82+
83+
When posting a zip, note the following
84+
85+
- only a single file can be attached to your post. If you add more than one, you'll get an error.
86+
- filename doesn't matter, as it won't be used
87+
- the archive's root will be treated as the root of the project, meaning all file paths will be mapped relative to this.
88+
89+
With CURL it would look like
90+
91+
curl -X POST -H "Content-Type: multipart/form-data" -H "Transfer-Encoding: chunked" -F "Files=@path/to/archive" http://tetriserver.example.com/v1/packages/myPackage?isArchive=true
92+
93+
Chunking the upload is important if your archive is large, as this might exceeded the multipart body attachment size.
94+
95+
### Posting an archive from NodeJS
96+
97+
This uses the request package (https://www.npmjs.com/package/request).
98+
99+
let request = require('request'),
100+
fs = require('fs'),
101+
formdata = {
102+
Files : fs.createReadStream('path/to/archive')
103+
};
104+
105+
request.post({url: 'http://tetriserver.example.com', formData: formdata}, function(err, httpResponse, body) {
106+
if (err) {
107+
return console.error('upload failed : ', err);
108+
}
109+
110+
console.log('Upload succeeded : ', body);
111+
});
112+
113+
## Tagging
114+
115+
### Curl
116+
117+
To add the tag "MyTag" to the package "MyPackage, use
118+
119+
curl -X POST http://tetriserver.example.com/v1/tags/MyTag/MyPackage
120+
121+
To remove the tag
122+
123+
curl -X DELETE http://tetriserver.example.com/v1/tags/MyTag/MyPackage
124+
125+
126+
## Pruning
127+
128+
Tetrifact has automated pruning to delete older packages to prevent disk overuse. All prune settings are kept in config.yml.
129+
130+
Pruning is disabled by default, to enable it use
131+
132+
...
133+
PruneEnabled : True
134+
...
135+
136+
Pruning behaviour works in brackets. A bracket is a period for the age of packages, and x number of packages of a given age can be kept. Using the example below
137+
138+
PruneBrackets :
139+
- Days: 1
140+
Amount: -1
141+
- Days : 3
142+
Amount : 5
143+
- Days : 5
144+
Amount : 4
145+
146+
The first bracket is for all packages up to 1 day old, an amount of -1 means prune none, ie, keep all packages that are up to a day old. The second bracket indicates that for all packages created more than 1 ago and less than 3 days ago, keep 5 packages.
147+
148+
Pruning can ignore packages marked with one or more tags, use the list
149+
150+
PruneIgnoreTags:
151+
- MyKeepTag
152+
- MyImportTag
153+
154+
Pruning runs at 2am server time by default, you can change this with
155+
156+
PruneCronMask: "0 3 * * *"
157+
158+

src/Tetrifact.Core/PruneService.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ public void Prune()
8282

8383
_log.LogInformation("*************************************** Finished prune exectution. **************************************************************************");
8484

85+
return;
8586
}
8687

8788
public PrunePlan GeneratePrunePlan()
8889
{
89-
// sort brackets oldest to most recent, clone to change settings without affecting original instances
90+
// sort brackets newest to oldest, clone to change settings without affecting original instances
9091
IList<PruneBracketProcess> processBrackets = _settings.PruneBrackets
9192
.Select(p => PruneBracketProcess.FromPruneBracket(p))
93+
.OrderBy(p => p.Days)
9294
.ToList();
9395

9496
IList<string> taggedKeep = new List<string>();
@@ -104,7 +106,7 @@ public PrunePlan GeneratePrunePlan()
104106
foreach(PruneBracketProcess pruneBracketProcess in processBrackets)
105107
{
106108
pruneBracketProcess.Ceiling = ceiling;
107-
pruneBracketProcess.Floor = pruneBracketProcess.Ceiling.AddDays(-1 * pruneBracketProcess.Days);
109+
pruneBracketProcess.Floor = utcNow.AddDays(-1 * pruneBracketProcess.Days);
108110
ceiling = pruneBracketProcess.Floor;
109111
}
110112

@@ -137,7 +139,7 @@ public PrunePlan GeneratePrunePlan()
137139
continue;
138140
}
139141

140-
report.Add($"Package \"{packageId}\" fits into prune bracket {matchingBracket}. This bracket now contains {matchingBracket.Keep.Count} keep packages.");
142+
report.Add($"Package \"{packageId}\" fits into prune bracket {matchingBracket}. This bracket currently contains {matchingBracket.Keep.Count} packages for keeping.");
141143
matchingBracket.Found++;
142144

143145
// try to find reasons to keep package

0 commit comments

Comments
 (0)