Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
938 commits
Select commit Hold shift + click to select a range
e80f9ca
Setting up for GCP and AWS clients by introducing s3 end point along …
tonytw1 Feb 25, 2026
4590b21
Image projector is bucket S3 endpoint aware.
tonytw1 Feb 24, 2026
f2e76b2
Image bucket takes end point config from config.
tonytw1 Nov 29, 2024
4ece32e
Ingest and rejected buckets have configurable end points.
tonytw1 Jan 17, 2025
2ca7392
Thumbs bucket has configurable end point.
tonytw1 Jan 24, 2025
75a5ba6
Configure a GCP S3 client and selectively use it based on the bucket …
tonytw1 Nov 29, 2024
72bf23b
v2 sigs on all AWS buckets for better caching.
tonytw1 Nov 30, 2024
96476dc
Signed S3 URLs come from bucket's client.
tonytw1 Dec 15, 2024
609a616
Setup a local Minio S3 client.
tonytw1 Jan 23, 2025
b8d1f12
Local S3.
tonytw1 Jan 23, 2025
f210215
Local S3.
tonytw1 Jan 23, 2025
64d7789
Local S3 urls to keys.
tonytw1 Jan 24, 2025
666293a
Local S3 - host.
tonytw1 Jan 24, 2025
08412f6
Kahuna UI can connect to ingest bucket endpoint.
tonytw1 Jan 25, 2025
a793496
Noisy log.
tonytw1 Apr 2, 2025
0465182
Noisy log Redact debug.
tonytw1 Apr 2, 2025
a67f35d
GCP S3 interop does not support S3 bulkDelete; reimplement as single …
tonytw1 Apr 13, 2025
677afde
Logging tidy up; storeImage
tonytw1 Apr 28, 2025
da5f5e7
Logging tidy up; thumbnail bucket.
tonytw1 Apr 28, 2025
4a2ea7b
Clean up; unused unit assignment.
tonytw1 Apr 28, 2025
3184b59
Logging; lower to debug.
tonytw1 Apr 28, 2025
f131f74
Logging; bucket name.
tonytw1 Apr 28, 2025
e5549cc
Logging; bucket name.
tonytw1 Apr 28, 2025
45164e6
Inject S3 into Crops from CropperComponents.
tonytw1 Feb 7, 2026
613e2fd
S3Object takes a full S3Bucket as it's bucket parameter. endpoint par…
tonytw1 Aug 9, 2025
016c9ed
S3 objectUrl for bucket and key can move to the bucket (which knows i…
tonytw1 Sep 14, 2025
91975f8
S3KeyFromURL move to S3Bucket as it know's it's own URL scheme.
tonytw1 Sep 14, 2025
2250059
Clean up; further isolating S3Client as the cloudfront concern.
tonytw1 Sep 14, 2025
31e06f3
Refactor; extracting the is path style URLs bucket decision.
tonytw1 Sep 14, 2025
5b41445
S3 path based URLs decision moves to bucket property and config.
tonytw1 Sep 14, 2025
960a715
Extract bucket base URL function.
tonytw1 Dec 13, 2025
44da344
Crops bucket can be on non AWS bucket.
tonytw1 Jan 25, 2026
c59f2f9
S3 Client moves onto the S3 Bucket.
tonytw1 Feb 7, 2026
75c144c
Overly verbose fileMarkers included the all the bucket client's fields.
tonytw1 Feb 21, 2026
36970b1
[gcp-storage-buckets] Crops bucket references from media-api for down…
tonytw1 Feb 9, 2026
cca4e54
[gcp-storage-buckets] uploadToQuarantineEnabled unused
tonytw1 Feb 25, 2026
d42ed87
JDK 25 build and runtime.
tonytw1 May 3, 2025
eb569e4
Docker client and server version mismatch during build.
tonytw1 Jan 1, 2026
1d12003
Test files used by ImageOps tests can move to the common-lib project …
tonytw1 May 3, 2025
60faf7b
Add vips-ffm as the Java vips binding.
tonytw1 May 3, 2025
5cdab9c
Spike; initial VIPS based thumbnail call.
tonytw1 May 3, 2025
153bde7
[libvips] extract save Vimage to file.
tonytw1 May 24, 2025
e38573f
[libvips] save image enable JPEG optimize-coding which appear to be a…
tonytw1 Jan 18, 2026
a91fc8c
ImageOperations users need to Vips.init().
tonytw1 May 10, 2025
c864ce8
thumbnail accounts for orientation rotation.
tonytw1 May 3, 2025
562740a
thumbnail save exports SRGB profile.
tonytw1 May 4, 2025
0fd40ed
Logging.
tonytw1 May 4, 2025
103073e
generateThumbnail does not attempt to check for ICC colour space mism…
tonytw1 May 5, 2025
28b7b7d
Nerf getColorModelInformation; costs many 100s of ms.
tonytw1 May 5, 2025
8478310
createThumbFuture no longer needs filemetaData.
tonytw1 May 8, 2025
c7d90d8
Remove transcodedMimeTypes and transformImage into browser viewable i…
tonytw1 May 8, 2025
774947b
Spike if we decide not to make a stored optimised png then we can dro…
tonytw1 May 8, 2025
ba183de
Spike vips_image_get_interpretation can identifyColourModel.
tonytw1 May 10, 2025
663465a
Tests for vips based identifyColourModel.
tonytw1 May 16, 2025
9e94656
Vips based colourInformation hasAlpha.
tonytw1 May 10, 2025
4f9ba11
Dimensions calls move to vips.
tonytw1 May 12, 2025
88da6fd
Inline Vips futures to be kinder on memory.
tonytw1 May 12, 2025
71751c8
Image orientation moves to vips.
tonytw1 May 13, 2025
6271835
Reorder; all vips images ops next to each other.
tonytw1 May 17, 2025
546dd05
Put dimensions and orientation operations behind a single interface.
tonytw1 May 17, 2025
80736df
Implement dimensions and orientation operations from the same vips im…
tonytw1 May 17, 2025
551e577
Put colour model and information operations behind a single interface.
tonytw1 May 17, 2025
cc2924e
Put colour model and information operations behind a single interface.
tonytw1 May 17, 2025
a2282b1
Merge colour model and information operations into a single Vips imag…
tonytw1 May 17, 2025
8c61493
Put all dimensions, orientation and colour calls under a single method.
tonytw1 May 17, 2025
0557102
Merge dimensions, orientation and colour calls under a single vips im…
tonytw1 May 17, 2025
e78d33f
Time getImageInformation.
tonytw1 May 18, 2025
a6046a7
thumbnail javadoc.
tonytw1 May 18, 2025
66978d6
Remove unused imagemagik thumbnail.
tonytw1 May 18, 2025
2840e62
Defer reading of file metadata until after we know we can read the im…
tonytw1 May 17, 2025
ba2e5a7
Time toFileMetadata.
tonytw1 May 18, 2025
934ebdf
Refactor; move thumb dimensions call closed to thumb generation.
tonytw1 May 18, 2025
5e3a52c
Log to show that we know the dimensions of created thumbnails.
tonytw1 May 18, 2025
805c14f
generate thumb nail returns the thumbs dimensions to avoid an immedia…
tonytw1 May 18, 2025
9403b1e
Set vips no cache; helps with long running memory?
tonytw1 May 19, 2025
1242cf8
VipsHelper might be less leaky then VipsRaw?
tonytw1 May 19, 2025
f7bd131
Move cache = 0 to init.
tonytw1 May 20, 2025
cdae4b4
Log exceptions inside vips.run.
tonytw1 May 20, 2025
d197b39
[libvips] Refactor; thumb can reuse saveImageToFile for Jpegs writing…
tonytw1 Jan 19, 2026
809bd0e
Manually manage arena to ensure it's explicitly closed.
tonytw1 May 20, 2025
a831cfe
Additional colour interreptations.
tonytw1 Jan 26, 2026
a1db546
Correct CMYK renders too light in thumbnails.
tonytw1 May 25, 2025
03a3060
[libvips] save files by mimeType
tonytw1 May 24, 2025
b234ea9
[libvips] Palettise PNG saved files.
tonytw1 May 25, 2025
342d016
[libvips] toOptimisedFile uses vips to transform from source to png.
tonytw1 Jan 12, 2026
5bcbbde
[libvips] Refactor; do not pass the static OptimiseWithPngQuant aroun…
tonytw1 Jan 16, 2026
fcfa564
[libvips] OptimiseWithPngQuant is a class so it's imageOps dependency…
tonytw1 Jan 16, 2026
9c57e49
[libvips] save image has option to quantise PNG
tonytw1 May 25, 2025
f7acc67
[libvips] OptimiseWithPngQuant should quantise it's output.
tonytw1 Jan 16, 2026
a2f60b9
[libvips] Log toOptimisedFile time.
tonytw1 Jan 17, 2026
3c1e5dc
[libvips] Save image explicitly mentions default PNG compression.
tonytw1 Feb 11, 2026
d64b9db
[libvips] png Q option is not needed if we are not actually quantisin…
tonytw1 Feb 12, 2026
3e4d878
[libvips] OptimizedOps needs to the same icc correction as cropping.
tonytw1 Feb 12, 2026
af7c0f9
Clean up; recoverWith exception handling and arena.close in createThu…
tonytw1 Feb 15, 2026
f274524
[libvips] VIPS enabled image loader and cropper can probably use a sm…
tonytw1 Jun 29, 2025
dbffeb2
[libvips] Test to exercise create thumbnail.
tonytw1 Jan 20, 2026
9a9f0b9
[libvips] Test for correct thumbnail of png with alpha.
tonytw1 Feb 1, 2026
3155bd5
[libvips] Test for correct thumbnail of a tif with alpha.
tonytw1 Feb 1, 2026
3363c1b
Additional thumbnail tests (LAB and LAB16)
tonytw1 Jan 31, 2026
a63987e
Spike; create master crop file via vips.
tonytw1 May 21, 2025
c845e1c
Naive resize crops to jpegs only step.
tonytw1 May 23, 2025
349d5f5
createCrops and resizeImageVips in same Future and arena to allow sha…
tonytw1 May 23, 2025
b64063d
Try to use 1 load of the source image across all resizes; do the resi…
tonytw1 May 23, 2025
d88df8e
createCrops takes the masterCrop as a VImage rather than a file.
tonytw1 May 23, 2025
d36d3c5
createMasterCrop moving to same arena.
tonytw1 May 23, 2025
166c52e
Remove colourModel check from createMasterCrop.
tonytw1 May 23, 2025
a73b39a
Logging. Show when we reload the master crop from disk.
tonytw1 May 23, 2025
92a3058
Correct arena close timing.
tonytw1 May 23, 2025
3ec25e1
createMasterCrop no Futures.
tonytw1 May 23, 2025
e9aab51
arena scope?
tonytw1 May 23, 2025
5bfd9b3
arena scope?
tonytw1 May 23, 2025
596fb7c
arena scope?
tonytw1 May 23, 2025
1b674b4
arena scope?
tonytw1 May 23, 2025
e0c958b
Spike; no reload of master crop image.
tonytw1 May 23, 2025
84bf7fd
Marking TODO; why local file for master crop.
tonytw1 May 24, 2025
f743f00
Log local resize file location.
tonytw1 May 24, 2025
250e4ff
PNG specific optimiseImage steps can move straight into the resizeIma…
tonytw1 May 24, 2025
335465b
Logging.
tonytw1 May 24, 2025
e377ba7
TODO Strip true is needed to stop exif auto correction until we can s…
tonytw1 May 24, 2025
a7b60e9
Revert "Revert "Master image converted to sRBG colour space.""
tonytw1 May 24, 2025
2acac71
Resize uses save file.
tonytw1 Feb 10, 2026
e327d80
Log crop type decision.
tonytw1 May 24, 2025
4de5344
Colour correct not effective if metadata stripped. Bake it in?
tonytw1 May 24, 2025
afab9d7
Refactor; master crop image file write pushes up out of the create ma…
tonytw1 May 24, 2025
76b3de3
createMasterCrop uses saveToFile and can now save PNGs.
tonytw1 Feb 10, 2026
eb202f3
Refactor. S3 store of master crop pushes up. MasterCrop is a simpler …
tonytw1 May 24, 2025
a2b8b9d
Refactor. File create for mastercrop pushes up to be next to the s3 s…
tonytw1 May 24, 2025
010ef6a
Master file create order; before arena close.
tonytw1 May 24, 2025
b8406b6
Comment; master crop if different from the the full dimensions crop; …
tonytw1 May 24, 2025
081f0b8
Refactor; split creation of crop files from publishing to S3.
tonytw1 May 25, 2025
9e6373b
quantise crops.
tonytw1 Feb 11, 2026
e6af963
isGraphic was sendint all TIFFs to PNG.
tonytw1 May 25, 2025
1a0f01c
isGraphic was sendint all TIFFs to PNG.
tonytw1 May 25, 2025
1ef36cb
Correct CMYK renders too light in crops.
tonytw1 May 25, 2025
07083a3
Unused parameters.
tonytw1 May 26, 2025
6dd8db3
Unused parameters.
tonytw1 May 26, 2025
dc35547
Bypass icc_transform for LAB images.
tonytw1 May 26, 2025
2e9a19c
Remove non used non vips functions.
tonytw1 Feb 28, 2026
bdca28f
Remove non used runConvert command.
tonytw1 May 26, 2025
0fd4e2a
Remove unused iccColourSpace val.
tonytw1 Jun 29, 2025
fbf4fae
Reapply png master quality.
tonytw1 Jun 29, 2025
a0d6d3c
Crop quality values can be int.
tonytw1 Jan 17, 2026
b20bd59
CropType decision can be deferred until after the master crop has bee…
tonytw1 Nov 24, 2025
cdde884
Refactor. Push the isGraphic? decision up out of cropType so that is …
tonytw1 Dec 29, 2025
383c732
Spike. vips based implementation of isGraphic? is likely to involve t…
tonytw1 Dec 29, 2025
d315d26
Test to exercise ImageOperations resize.
tonytw1 Feb 18, 2026
4519e31
[libvips] Testing around hasAlpha.
tonytw1 Feb 1, 2026
c193b19
Clarify master crop quality values.
tonytw1 Jan 17, 2026
6e77178
[libvips-cropping] Allow embedded icc profile to be used in crop icc …
tonytw1 Jan 19, 2026
8789c44
[libvips-cropping] Image operations resize takes the output file as a…
tonytw1 Jan 21, 2026
869853d
[libvips-cropping] Cropping of LAB fixed by making non icc_transform …
tonytw1 Jan 19, 2026
77f7756
[libvips-cropping] Show that it is possible to manually trim metadata…
tonytw1 Feb 12, 2026
aed71f4
[libvips-cropping] Bake the credit, copyright and supplier transmissi…
tonytw1 Jan 24, 2026
7e343c2
XMP Credit -> photoshop:Credit
tonytw1 Feb 24, 2026
82030eb
XMP Byline -> creator.
tonytw1 Feb 24, 2026
3b8c9db
[libvips-cropping] While manually stripping metadata might be useful,…
tonytw1 Feb 12, 2026
27db572
[libvips-cropping] Additional resize tests.
tonytw1 Jan 31, 2026
10a9f24
[libvips-cropping] Test for correct resize of png with alpha.
tonytw1 Feb 16, 2026
e38d6d9
[libvips-cropping] Provide an example of the vips can't render a LAB …
tonytw1 Jan 31, 2026
d3ddf8a
[libvips-cropping] Cleanup; Lower the input of apiSource to imageId f…
tonytw1 Jan 26, 2026
c1979d9
[libvips-cropping] resizeImageVips does not need the MasterCrop object
tonytw1 Mar 15, 2026
12cb734
[libvips-cropping] Metadata for crop call.
tonytw1 Feb 1, 2026
256ee85
[libvips-cropping] Crop metadata in XMP via vips removes exiftool as …
tonytw1 Jan 24, 2026
bbb8647
[libvips-cropping] createCrops moves to image operations for testing.
tonytw1 Jan 26, 2026
5b088dc
[libvips-cropping] Tests to exercise crops.
tonytw1 Jan 31, 2026
6bbf37d
[libvips-cropping] createCrops can execute it's resizeImage calls in …
tonytw1 Mar 15, 2026
7a01025
[libvips-cropping] Master crop save in parallel.
tonytw1 Jan 26, 2026
c8abe6f
[libvips-cropping] Logging.
tonytw1 Jan 26, 2026
fc7ab81
[libvips-cropping] Logging and imports.
tonytw1 Jan 26, 2026
e9382ec
[libvips-cropping] Do not send resizes until master has successfully …
tonytw1 Jan 27, 2026
a9ef182
[libvips-cropping] getImageInformation uses imageOperations.hasAlpha …
tonytw1 Feb 1, 2026
560c0f3
[libvips-cropping] Missing arena.close()
tonytw1 Feb 24, 2026
220d394
[libvips-cropping] Crops uses master hasAlpha image operation rather …
tonytw1 Feb 1, 2026
56fd25c
[libvips-cropping] Do not repeat calls to image_get_interpretation
tonytw1 Feb 24, 2026
3983ebd
Removes exiftool from base image.
tonytw1 Feb 20, 2026
b6e99a5
Remove pnquant from base image.
tonytw1 Jan 13, 2026
2c6e544
Reindexing from S3. Thrall endpoint to trigger a projection of all S3…
tonytw1 Sep 23, 2024
ac6bf9a
Reindex is bucket aware (what was it doing before?)
tonytw1 Dec 1, 2024
1d325f5
Reindex process queues project image operations.
tonytw1 Mar 30, 2025
ff8edcd
Reindex should write projection results as UpsertFromProjectionMessag…
tonytw1 Mar 30, 2025
4249b52
Reindex logging message.
tonytw1 Apr 18, 2025
ff65906
Reindex messages are put into the low priority queue.
tonytw1 Apr 18, 2025
48e1a0a
[reindexing] Form to request reindex of single image.
tonytw1 Mar 25, 2026
3bbbcb6
[reindexing] S3 reindexing logging.
tonytw1 Mar 25, 2026
ebcec59
[reindexing] Reindex from CSV end point.
tonytw1 Mar 25, 2026
72b5c89
[reindexing] Prompt fort full reindex.
tonytw1 Mar 26, 2026
c7e9f69
[reindexing] Combine.
tonytw1 Mar 26, 2026
b8e669f
[reindexing] Send reindexMessages in batches for faster enqueuing.
tonytw1 Mar 26, 2026
cd79c75
Queue reindex requests by most recently last modified first.
tonytw1 Mar 26, 2026
7bb17d2
Reindex kinesis stream runs separately with it's own concurrency.
tonytw1 Mar 27, 2026
2d2d28f
Spike; simpler SyndicationFilter
tonytw1 Sep 18, 2025
57905da
Add syndicationStatus as as filter in the q parameter so that it can …
tonytw1 Sep 19, 2025
8a98968
Filter test.
tonytw1 Sep 19, 2025
f2cb38c
Queued for syndication must be syndicatableCategory / owned not just …
tonytw1 Oct 5, 2025
7b89696
Image.syndicationStatus aligns with syndicationFilter on not needing …
tonytw1 Oct 11, 2025
afd2232
Image.syndicationStatus aligns with syndicationFilter on defination o…
tonytw1 Oct 12, 2025
61d1b1a
Update ImageTest syndication tests to match isOwned syndication right…
tonytw1 Dec 30, 2025
b09f5aa
Update ElasticSearchTest syndication tests to match isOwned syndicati…
tonytw1 Dec 30, 2025
de5ea84
syndicationStatus query suggestion in UI.
tonytw1 Feb 5, 2026
711192f
Get getCssColour supports sub folder colours overriding parent colour…
tonytw1 Aug 2, 2025
156dc21
Extract collection paths for reuse in CssColours.
tonytw1 Aug 2, 2025
64582b2
Recent print usages highlight only counts recent published usages.
tonytw1 Jun 21, 2025
95747b4
Refactor; image screen usage panel considers whole usage when making …
tonytw1 Jun 21, 2025
7ed97b0
Image screen usage panel does not highlight non published print uses …
tonytw1 Jun 21, 2025
e58666a
Update Observer collection colours.
tonytw1 Jun 22, 2025
330d34e
Fork Tortoise usage rights with minimal config.
tonytw1 Feb 13, 2025
17896fb
Add GNM as an agency.
tonytw1 Feb 13, 2025
8e47578
Set Tortoise contact photographers.
tonytw1 Apr 10, 2025
5bcbc8e
Chris Riddell is an Observer contacted illustrator.
tonytw1 Jun 22, 2025
3ce901c
Remove Dave Benett Collection from list of explicity pay to use Getty…
tonytw1 Feb 25, 2026
a6f4bcd
v2 sigs do not work for buckets created after June 2024.
tonytw1 Sep 23, 2025
b8e2487
migrationStatusRefresher interval.
tonytw1 Sep 24, 2025
4c776b7
Thrall "/thrall" prefix via explicit Routes.withPrefix because play.h…
tonytw1 Nov 16, 2025
188ea69
No +nocsrf on thrall UI routes.
tonytw1 Nov 16, 2025
712a5ba
Usages updates should go on the main kinesis stream so that they are …
tonytw1 Nov 16, 2025
610409e
Revert "remove preview view"
tonytw1 Nov 26, 2025
66cec52
Fixes stickiness when paging through preview images.
tonytw1 Nov 26, 2025
a9471b7
Immutable placeholders look out of place; change to allow ids to upda…
tonytw1 Nov 27, 2025
95e418d
Fixes inSelectionMode not been past to ui-preview-image-large. Fixes …
tonytw1 Nov 27, 2025
8f5d872
Allow more than 1 item to be selected from preview mode. Allow range …
tonytw1 Nov 29, 2025
bdbeb0f
Always show reapable filter.
tonytw1 Feb 5, 2026
bd04b28
Media API offers an end point for downloading the master crop.
tonytw1 Feb 20, 2026
56ab00d
Kahana picks up master asset for download.
tonytw1 Feb 20, 2026
4579c00
Digital usage webTitle and sectionId are optional.
tonytw1 Feb 21, 2026
6b6b0ba
Enable iPhone HEIC support.
tonytw1 May 26, 2025
63eaec1
Kahuna only build for faster UI dev.
tonytw1 Mar 1, 2026
7f6c706
Explicit human-readable crop display names.
tonytw1 Jan 11, 2025
c9d3d86
Register 3:2 as a known aspect ratio so that in can be cleaned with t…
tonytw1 Dec 7, 2024
30d20ff
Register 3:2 as a crop option.
tonytw1 Dec 7, 2024
203193a
Observer wants 5:3 crop options.
tonytw1 Mar 1, 2026
7e0b34e
Crops download as the original filename falling back to Grid image id…
tonytw1 Mar 8, 2026
8c2175b
Disable reaping of S3 vectors.
tonytw1 Mar 22, 2026
007db81
Set start dates for publication photographers to 22 April 2025 for r…
tonytw1 Mar 25, 2026
5ed5576
Logging.
tonytw1 Mar 26, 2026
8df8fc1
libvips 8.18.2 base image.
tonytw1 Apr 6, 2026
b75f4c7
Use libvips 8.18.2 base image.
tonytw1 Apr 6, 2026
05f0e81
vips-ffm 1.9.6
tonytw1 Apr 6, 2026
161229e
Revert "[upstream] Capture print%2F usage ids."
tonytw1 Apr 6, 2026
3b24215
Testing around hasAlpha for LAB8 and LAB16
tonytw1 Feb 22, 2026
4c0402e
Comment out lab16 alpha check; no fix available yet.
tonytw1 Feb 22, 2026
4e3b938
Lab tiff with alpha can only be reliability rendered with we drop the…
tonytw1 Feb 19, 2026
dd3b428
hasAlpha function gets a correct no alpha decision of we force INTERP…
tonytw1 Feb 1, 2026
0eec370
[lib-vipscroping] Test for isAlpha TIFF with alpha.
tonytw1 Feb 1, 2026
0dd736b
Additional tests for LAB TIFF with alpha.
tonytw1 Feb 1, 2026
c3dff13
WIP - accidental plausible LAB alpga output!
tonytw1 Feb 1, 2026
cc5b050
Revert
tonytw1 Feb 2, 2026
9059bba
resize Lab16 with alpha test.
tonytw1 Feb 2, 2026
5f2b679
Testing render LAB colour spaces with alpha correctly in sRGB
tonytw1 Feb 16, 2026
d6609b2
Optimise PNG for TIFFs for testing proposes.
tonytw1 Jan 12, 2026
646dde9
Logging.
tonytw1 Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 9 additions & 0 deletions .github/workflows/check-labels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: CORE4 label enforcement
permissions:
contents: read
on:
pull_request:
types: [opened, labeled, unlabeled, synchronize, reopened, edited]
jobs:
require-label:
uses: guardian/.github/.github/workflows/require-label.yaml@4cb5024736632ffcc564b7f4b772c38b8e5ce739 # v2.0.0
21 changes: 15 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
pull-requests: write
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.16.2
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.29
# Wait for elasticsearch to report healthy before continuing.
# see https://github.com/actions/example-services/blob/master/.github/workflows/postgres-service.yml#L28
options: -e "discovery.type=single-node" --expose 9200 --health-cmd "curl localhost:9200/_cluster/health" --health-interval 10s --health-timeout 5s --health-retries 10
Expand All @@ -36,11 +36,13 @@ jobs:
--health-timeout 5s
--health-retries 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6.0.2
- name: Setup Node
uses: actions/setup-node@v3
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "cdk/package-lock.json"
- name: Kahuna (client-side)
working-directory: ./kahuna
run: |
Expand Down Expand Up @@ -72,7 +74,11 @@ jobs:
npm install-clean
npm test
npm run build
- uses: guardian/actions-riff-raff@v4.2.3
- name: Image embedder cdk
run: ./scripts/embedder-deploy/cdk.sh
- name: Image embedder bundling
run: ./scripts/embedder-deploy/build.sh
- uses: guardian/actions-riff-raff@v4.2.4
if: "! github.event.pull_request.head.repo.fork"
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -107,5 +113,8 @@ jobs:

image-counter-lambda:
- image-counter-lambda/dist/image-counter-lambda.zip



cdk.out:
- cdk/cdk.out
image-embedder-lambda:
- image-embedder.zip
2 changes: 1 addition & 1 deletion .github/workflows/push-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
contents: write
actions: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6.0.2
- name: push-pr
env:
PR: ${{ inputs.prNumber }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/sbt-dependency-graph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ jobs:
steps:
- name: Checkout branch
id: checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6.0.1
- name: Install Java
id: java
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.2.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: corretto
java-version: 17
- name: Install sbt
id: sbt
uses: sbt/setup-sbt@8a071aa780c993c7a204c785d04d3e8eb64ef272 # v1.1.0
uses: sbt/setup-sbt@3e125ece5c3e5248e18da9ed8d2cce3d335ec8dd # v1.1.14
- name: Submit dependencies
id: submit
uses: scalacenter/sbt-dependency-submission@64084844d2b0a9b6c3765f33acde2fbe3f5ae7d3 # v3.1.0
uses: scalacenter/sbt-dependency-submission@f43202114d7522a4b233e052f82c2eea8d658134 # v3.2.1
- name: Log snapshot for user validation
id: validate
run: cat ${{ steps.submit.outputs.snapshot-json-path }} | jq
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ dev/config/permissions.json

coverage/
.bsp

image-embedder.zip

# Integration test data (cached S3 downloads and outputs)
image-embedder-lambda/__tests__/integration/test-data/
5 changes: 2 additions & 3 deletions auth/app/auth/AuthComponents.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package auth

import com.gu.mediaservice.lib.management.{InnerServiceStatusCheckController, Management}
import com.gu.mediaservice.lib.management.Management
import com.gu.mediaservice.lib.play.GridComponents
import play.api.ApplicationLoader.Context
import play.api.{Configuration, Environment}
Expand All @@ -14,10 +14,9 @@ class AuthComponents(context: Context) extends GridComponents(context, new AuthC

val controller = new AuthController(auth, providers, config, controllerComponents, authorisation)
val permissionsAwareManagement = new Management(controllerComponents, buildInfo)
val InnerServiceStatusCheckController = new InnerServiceStatusCheckController(auth, controllerComponents, config.services, wsClient)


override val router = new Routes(httpErrorHandler, controller, permissionsAwareManagement, InnerServiceStatusCheckController)
override val router = new Routes(httpErrorHandler, controller, permissionsAwareManagement)
}

object AuthHttpConfig {
Expand Down
6 changes: 4 additions & 2 deletions auth/app/auth/AuthConfig.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package auth

import com.gu.mediaservice.lib.config.{CommonConfig, GridConfigResources}
import com.gu.mediaservice.model.Instance

class AuthConfig(resources: GridConfigResources) extends CommonConfig(resources) {
val rootUri: String = services.authBaseUri
val mediaApiUri: String = services.apiBaseUri
val rootUri: Instance => String = services.authBaseUri
val rootInstanceUri: Instance => String = services.authBaseInstanceUri
val mediaApiUri: Instance => String = services.apiBaseUri
}
21 changes: 13 additions & 8 deletions auth/app/auth/AuthController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import com.gu.mediaservice.lib.auth.Authentication.{InnerServicePrincipal, Machi
import com.gu.mediaservice.lib.auth.Permissions.{DeleteImage, ShowPaid, UploadImages}
import com.gu.mediaservice.lib.auth.provider.AuthenticationProviders
import com.gu.mediaservice.lib.auth.{Authentication, Authorisation, Internal}
import com.gu.mediaservice.lib.config.InstanceForRequest
import com.gu.mediaservice.lib.guardian.auth.PandaAuthenticationProvider
import com.gu.mediaservice.model.Instance
import play.api.libs.json.Json
import play.api.mvc.{BaseController, ControllerComponents, Result}
import play.api.mvc.{AnyContent, BaseController, ControllerComponents, Request, Result}

import java.net.URI
import java.util.Date
Expand All @@ -19,15 +21,15 @@ class AuthController(auth: Authentication, providers: AuthenticationProviders, v
override val controllerComponents: ControllerComponents,
authorisation: Authorisation)(implicit ec: ExecutionContext)
extends BaseController
with ArgoHelpers {
with ArgoHelpers with InstanceForRequest {

val indexResponse = {
def indexResponse()(implicit instance: Instance) = {
val indexData = Map("description" -> "This is the Auth API")
val indexLinks = List(
Link("root", config.mediaApiUri),
Link("login", config.services.loginUriTemplate),
Link("ui:logout", s"${config.rootUri}/logout"),
Link("session", s"${config.rootUri}/session")
Link("root", config.mediaApiUri(instance)),
Link("login", config.services.loginUriTemplate(instance)),
Link("ui:logout", s"${config.rootUri(instance)}/logout"),
Link("session", s"${config.rootInstanceUri(instance)}/session")
)
respond(indexData, indexLinks)
}
Expand All @@ -42,7 +44,10 @@ class AuthController(auth: Authentication, providers: AuthenticationProviders, v
}
}

def index = auth { indexResponse }
def index = auth { request =>
implicit val instance: Instance = instanceOf(request)
indexResponse()
}

def session = auth { request =>
val showPaid = authorisation.hasPermissionTo(ShowPaid)(request.user)
Expand Down
1 change: 0 additions & 1 deletion auth/conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ GET /cookieMonster auth.AuthController.cookieMonster
# Management
GET /management/healthcheck com.gu.mediaservice.lib.management.Management.healthCheck
GET /management/manifest com.gu.mediaservice.lib.management.Management.manifest
GET /management/whoAmI com.gu.mediaservice.lib.management.InnerServiceStatusCheckController.whoAmI(depth: Int)

# Shoo robots away
GET /robots.txt com.gu.mediaservice.lib.management.Management.disallowRobots
99 changes: 59 additions & 40 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import play.sbt.PlayImport.PlayKeys._
import com.typesafe.sbt.packager.docker.*
import play.sbt.PlayImport.PlayKeys.*
import sbt.Package.FixedTimestamp

import scala.sys.process._
import scala.collection.JavaConverters.*
import scala.sys.process.*
import scala.util.control.NonFatal
import scala.collection.JavaConverters._

import com.typesafe.sbt.packager.debian.JDebPackaging

// We need to keep the timestamps to allow caching headers to work as expected on assets.
// The below should work, but some problem in one of the plugins (possible the play plugin? or sbt-web?) causes
Expand All @@ -21,7 +20,7 @@ ThisBuild / libraryDependencySchemes +=
"org.scala-lang.modules" %% "scala-java8-compat" % VersionScheme.Always

val commonSettings = Seq(
scalaVersion := "2.13.16",
scalaVersion := "2.13.18",
description := "grid",
organization := "com.gu",
version := "0.1",
Expand All @@ -39,6 +38,7 @@ val commonSettings = Seq(
"org.scalatestplus" %% "mockito-3-4" % "3.1.4.0" % Test,
"org.mockito" % "mockito-core" % "2.18.0" % Test,
"org.scalamock" %% "scalamock" % "5.1.0" % Test,
"org.testcontainers" % "localstack" % "1.21.4" % Test
),
dependencyOverrides += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.19.0",

Expand All @@ -63,7 +63,7 @@ Global / concurrentRestrictions := Seq(
)

val awsSdkVersion = "1.12.470"
val awsSdkV2Version = "2.31.12"
val awsSdkV2Version = "2.32.33"
val elastic4sVersion = "8.18.2"
val okHttpVersion = "3.12.1"

Expand All @@ -84,16 +84,17 @@ lazy val commonLib = project("common-lib").settings(
"com.amazonaws" % "aws-java-sdk-cloudwatch" % awsSdkVersion,
"com.amazonaws" % "aws-java-sdk-cloudfront" % awsSdkVersion,
"com.amazonaws" % "aws-java-sdk-sqs" % awsSdkVersion,
"software.amazon.awssdk" % "sqs" % awsSdkV2Version,
"com.amazonaws" % "aws-java-sdk-sns" % awsSdkVersion,
"com.amazonaws" % "aws-java-sdk-sts" % awsSdkVersion,
"com.amazonaws" % "aws-java-sdk-dynamodb" % awsSdkVersion,
"com.amazonaws" % "aws-java-sdk-kinesis" % awsSdkVersion,
"nl.gn0s1s" %% "elastic4s-core" % elastic4sVersion,
"nl.gn0s1s" %% "elastic4s-client-esjava" % elastic4sVersion,
"nl.gn0s1s" %% "elastic4s-domain" % elastic4sVersion,
"com.gu" %% "thrift-serializer" % "5.0.2",
"org.scalaz" %% "scalaz-core" % "7.3.8",
"org.im4java" % "im4java" % "1.4.0",
"app.photofox.vips-ffm" % "vips-ffm-core" % "1.9.6",
"com.gu" % "kinesis-logback-appender" % "1.4.4",
"net.logstash.logback" % "logstash-logback-encoder" % "5.0",
logback, // play-logback; needed when running the scripts
Expand All @@ -107,8 +108,13 @@ lazy val commonLib = project("common-lib").settings(
"org.scanamo" %% "scanamo" % "2.0.0",
// declare explicit dependency on desired version of aws sdk v2 dynamo
"software.amazon.awssdk" % "dynamodb" % awsSdkV2Version,
"software.amazon.awssdk" % "dynamodb-enhanced" % awsSdkV2Version,
// declare explicit dependency on desired version of aws sdk v2 bedrock runtime
"software.amazon.awssdk" % "bedrockruntime" % awsSdkV2Version,
"software.amazon.awssdk" % "s3vectors" % awsSdkV2Version,
"com.adobe.xmp" % "xmpcore" % "6.1.11",
ws,
"org.testcontainers" % "elasticsearch" % "1.19.2" % Test
"org.testcontainers" % "testcontainers-elasticsearch" % "2.0.2" % Test,
),
dependencyOverrides += "ch.qos.logback" % "logback-classic" % "1.2.13" % Test
)
Expand All @@ -125,11 +131,11 @@ lazy val auth = playProject("auth", 9011)

lazy val collections = playProject("collections", 9010)

lazy val cropper = playProject("cropper", 9006)
lazy val cropper = playImageLoaderProject("cropper", 9006)

lazy val imageLoader = playProject("image-loader", 9003).settings {
lazy val imageLoader = playImageLoaderProject("image-loader", 9003).settings {
libraryDependencies ++= Seq(
"org.apache.tika" % "tika-core" % "1.28.5",
"org.apache.tika" % "tika-core" % "3.2.3",
"com.drewnoakes" % "metadata-extractor" % "2.19.0"
)
}
Expand Down Expand Up @@ -164,8 +170,9 @@ lazy val thrall = playProject("thrall", 9002)
"software.amazon.awssdk" % "kinesis" % awsSdkV2Version,
"software.amazon.awssdk" % "dynamodb" % awsSdkV2Version,
"com.gu" %% "kcl-pekko-stream" % "0.1.0",
"org.testcontainers" % "elasticsearch" % "1.19.2" % Test,
"com.google.protobuf" % "protobuf-java" % "3.19.6"
"org.testcontainers" % "testcontainers-elasticsearch" % "2.0.2" % Test,
"com.google.protobuf" % "protobuf-java" % "3.19.6",
"software.amazon.awssdk" % "sqs" % awsSdkV2Version
),
// amazon-kinesis-client 2.6.0 brings in a critically vulnerable version of apache avro,
// but we cannot upgrade amazon-kinesis-client further without performing the v2->v3 upgrade https://docs.aws.amazon.com/streams/latest/dev/kcl-migration-from-2-3.html
Expand All @@ -177,8 +184,6 @@ lazy val thrall = playProject("thrall", 9002)

lazy val usage = playProject("usage", 9009).settings(
libraryDependencies ++= Seq(
"com.gu" %% "content-api-client-default" % "32.0.0",
"com.gu" %% "content-api-client-aws" % "0.7.6",
"io.reactivex" %% "rxscala" % "0.27.0",
// amazon-kinesis-client brings in a critical vulnerability warning through apache avro, resolved in versions 1.11.4 and 1.12.0.
// updating amazon-kinesis-client? check if the override below can be removed
Expand Down Expand Up @@ -233,39 +238,53 @@ val buildInfo = Seq(
)

def playProject(projectName: String, port: Int, path: Option[String] = None): Project = {
val commonProject = project(projectName, path)
.enablePlugins(PlayScala, JDebPackaging, SystemdPlugin, BuildInfoPlugin)
project(projectName, path)
.enablePlugins(PlayScala, BuildInfoPlugin, DockerPlugin)
.dependsOn(restLib)
.settings(commonSettings ++ buildInfo ++ Seq(
dockerBaseImage := "eclipse-temurin:25",
dockerExposedPorts := Seq(port),
playDefaultPort := port,
debianPackageDependencies := Seq("java11-runtime-headless"),
Linux / maintainer := "Guardian Developers <dig.dev.software@theguardian.com>",
Linux / packageSummary := description.value,
packageDescription := description.value,

bashScriptEnvConfigLocation := Some("/etc/environment"),
Debian / makeEtcDefault := None,
Debian / packageBin := {
val originalFileName = (Debian / packageBin).value
val (base, ext) = originalFileName.baseAndExt
val newBase = base.replace(s"_${version.value}_all","")
val newFileName = file(originalFileName.getParent) / s"$newBase.$ext"
IO.move(originalFileName, newFileName)
println(s"Renamed $originalFileName to $newFileName")
newFileName
},
Universal / mappings ++= Seq(
file("common-lib/src/main/resources/application.conf") -> "conf/application.conf",
file("common-lib/src/main/resources/logback.xml") -> "conf/logback.xml"
),
Universal / javaOptions ++= Seq(
"-Dpidfile.path=/dev/null",
s"-Dconfig.file=/usr/share/$projectName/conf/application.conf",
s"-Dlogger.file=/usr/share/$projectName/conf/logback.xml",
"-J-Xlog:gc*",
s"-J-Xlog:gc:/var/log/$projectName/gc.log"
)
))
//Add the BBC library dependency if defined
maybeBBCLib.fold(commonProject){commonProject.dependsOn(_)}
s"-Dconfig.file=/opt/docker/conf/application.conf",
s"-Dlogger.file=/opt/docker/conf/logback.xml",
"-XX:+PrintCommandLineFlags", "-XX:MaxRAMPercentage=40"
))
)
}

def playImageLoaderProject(projectName: String, port: Int, path: Option[String] = None): Project = {
project(projectName, path)
.enablePlugins(PlayScala, BuildInfoPlugin, DockerPlugin)
.dependsOn(restLib)
.settings(commonSettings ++ buildInfo ++ Seq(
dockerBaseImage := "eu.gcr.io/grid-301122/jdk-vips:25-8.18.2",
dockerExposedPorts := Seq(port),
dockerCommands ++= Seq(
Cmd("ENV", "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so")
),
playDefaultPort := port,

bashScriptEnvConfigLocation := Some("/etc/environment"),
Universal / mappings ++= Seq(
file("common-lib/src/main/resources/application.conf") -> "conf/application.conf",
file("common-lib/src/main/resources/logback.xml") -> "conf/logback.xml",
file("image-loader/cmyk.icc") -> "cmyk.icc",
file("image-loader/facebook-TINYsRGB_c2.icc") -> "facebook-TINYsRGB_c2.icc",
file("image-loader/grayscale.icc") -> "grayscale.icc",
file("image-loader/srgb.icc") -> "srgb.icc"
),
Universal / javaOptions ++= Seq(
"-Dpidfile.path=/dev/null",
s"-Dconfig.file=/opt/docker/conf/application.conf",
s"-Dlogger.file=/opt/docker/conf/logback.xml",
"-XX:+PrintCommandLineFlags", "-XX:MaxRAMPercentage=20"
)))
}
11 changes: 11 additions & 0 deletions cdk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*.js
!jest.config.js
!jest.setup.js
!.eslintrc.js
*.d.ts
node_modules
dist

# CDK asset staging directory
.cdk.staging
cdk.out
5 changes: 5 additions & 0 deletions cdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Infrastructure

This directory defines the components to be deployed to AWS.

See [`package.json`](./package.json) for a list of available scripts.
Loading