@@ -1545,6 +1545,23 @@ COPY %s .`, testImageAlpine, inclFile)
1545
1545
func TestPushImage (t * testing.T ) {
1546
1546
t .Parallel ()
1547
1547
1548
+ // Write a test feature to an in-memory registry.
1549
+ testFeature := registrytest .WriteContainer (t , registrytest .New (t ), "features/test-feature:latest" , features .TarLayerMediaType , map [string ]any {
1550
+ "install.sh" : `#!/bin/sh
1551
+ echo "${MESSAGE}" > /root/message.txt` ,
1552
+ "devcontainer-feature.json" : features.Spec {
1553
+ ID : "test-feature" ,
1554
+ Name : "test feature" ,
1555
+ Version : "v0.0.1" ,
1556
+ Options : map [string ]features.Option {
1557
+ "message" : {
1558
+ Type : "string" ,
1559
+ Default : "hello world" ,
1560
+ },
1561
+ },
1562
+ },
1563
+ })
1564
+
1548
1565
t .Run ("CacheWithoutPush" , func (t * testing.T ) {
1549
1566
t .Parallel ()
1550
1567
@@ -1557,12 +1574,15 @@ WORKDIR $WORKDIR
1557
1574
ENV FOO=bar
1558
1575
RUN echo $FOO > /root/foo.txt
1559
1576
RUN date --utc > /root/date.txt` , testImageAlpine ),
1560
- ".devcontainer/devcontainer.json" : `{
1577
+ ".devcontainer/devcontainer.json" : fmt . Sprintf ( `{
1561
1578
"name": "Test",
1562
1579
"build": {
1563
1580
"dockerfile": "Dockerfile"
1564
1581
},
1565
- }` ,
1582
+ "features": {
1583
+ %q: {}
1584
+ }
1585
+ }` , testFeature ),
1566
1586
},
1567
1587
})
1568
1588
@@ -1603,7 +1623,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
1603
1623
envbuilderEnv ("CACHE_REPO" , testRepo ),
1604
1624
envbuilderEnv ("GET_CACHED_IMAGE" , "1" ),
1605
1625
}})
1606
- require .ErrorContains (t , err , " uncached COPY command is not supported in cache probe mode" )
1626
+ require .Regexp (t , ` uncached.* command.* is not supported in cache probe mode` , err . Error () )
1607
1627
})
1608
1628
1609
1629
t .Run ("CacheAndPush" , func (t * testing.T ) {
@@ -1612,21 +1632,27 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
1612
1632
ctx , cancel := context .WithCancel (context .Background ())
1613
1633
t .Cleanup (cancel )
1614
1634
1635
+ // Given: a git repository with a devcontainer.json that references the
1636
+ // feature
1615
1637
srv := gittest .CreateGitServer (t , gittest.Options {
1616
1638
Files : map [string ]string {
1617
1639
".devcontainer/Dockerfile" : fmt .Sprintf (`FROM %s
1618
- USER root
1619
- ARG WORKDIR=/
1620
- WORKDIR $WORKDIR
1621
- ENV FOO=bar
1622
- RUN echo $FOO > /root/foo.txt
1623
- RUN date --utc > /root/date.txt` , testImageAlpine ),
1624
- ".devcontainer/devcontainer.json" : `{
1625
- "name": "Test",
1626
- "build": {
1627
- "dockerfile": "Dockerfile"
1628
- },
1629
- }` ,
1640
+ USER root
1641
+ ARG WORKDIR=/
1642
+ WORKDIR $WORKDIR
1643
+ ENV FOO=bar
1644
+ RUN echo $FOO > /root/foo.txt
1645
+ RUN date --utc > /root/date.txt` , testImageAlpine ),
1646
+ ".devcontainer/devcontainer.json" : fmt .Sprintf (`
1647
+ {
1648
+ "name": "Test",
1649
+ "build": {
1650
+ "dockerfile": "Dockerfile"
1651
+ },
1652
+ "features": {
1653
+ %q: {}
1654
+ }
1655
+ }` , testFeature ),
1630
1656
},
1631
1657
})
1632
1658
@@ -1671,6 +1697,9 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
1671
1697
require .Regexp (t , `(?s)^USAGE:\s+envbuilder` , strings .TrimSpace (out ))
1672
1698
out = execContainer (t , ctr .ID , "cat /root/date.txt" )
1673
1699
require .NotEmpty (t , strings .TrimSpace (out ))
1700
+ // Then: the feature install script was run
1701
+ out = execContainer (t , ctr .ID , "cat /root/message.txt" )
1702
+ require .Equal (t , "hello world" , strings .TrimSpace (out ))
1674
1703
})
1675
1704
1676
1705
t .Run ("CacheAndPushDevcontainerOnly" , func (t * testing.T ) {
@@ -1702,7 +1731,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
1702
1731
_ , err = runEnvbuilder (t , runOpts {env : append (opts ,
1703
1732
envbuilderEnv ("GET_CACHED_IMAGE" , "1" ),
1704
1733
)})
1705
- require .ErrorContains (t , err , "error probing build cache: uncached COPY command" )
1734
+ require .Regexp (t , "error probing build cache: uncached.*command.*is not supported in cache probe mode" , err . Error () )
1706
1735
// Then: it should fail to build the image and nothing should be pushed
1707
1736
_ , err = remote .Image (ref )
1708
1737
require .ErrorContains (t , err , "NAME_UNKNOWN" , "expected image to not be present before build + push" )
@@ -2293,26 +2322,23 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
2293
2322
require .NoError (t , err )
2294
2323
})
2295
2324
2296
- t .Run ("CacheAndPushDevcontainerFeatures " , func (t * testing.T ) {
2325
+ t .Run ("CacheAndPushDevcontainerFeaturesOverrideOption " , func (t * testing.T ) {
2297
2326
t .Parallel ()
2298
2327
2299
2328
ctx , cancel := context .WithCancel (context .Background ())
2300
2329
t .Cleanup (cancel )
2301
2330
2302
2331
srv := gittest .CreateGitServer (t , gittest.Options {
2303
2332
Files : map [string ]string {
2304
- // NOTE(mafredri): We can't cache the feature in our local
2305
- // registry because the image media type is incompatible.
2306
2333
".devcontainer/devcontainer.json" : fmt .Sprintf (`
2307
- {
2308
- "image": %q,
2309
- "features": {
2310
- "ghcr.io/devcontainers/feature-starter/color:1": {
2311
- "favorite": "green"
2312
- }
2313
- }
2314
- }
2315
- ` , testImageUbuntu ),
2334
+ {
2335
+ "image": %q,
2336
+ "features": {
2337
+ %q: {
2338
+ "message": "my favorite color is green"
2339
+ }
2340
+ }
2341
+ }` , testImageUbuntu , testFeature ),
2316
2342
},
2317
2343
})
2318
2344
@@ -2343,7 +2369,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
2343
2369
ctr := startContainerFromRef (ctx , t , cli , cachedRef )
2344
2370
2345
2371
// Check that the feature is present in the image.
2346
- out := execContainer (t , ctr .ID , "/usr/local/bin/color " )
2372
+ out := execContainer (t , ctr .ID , "cat /root/message.txt " )
2347
2373
require .Contains (t , strings .TrimSpace (out ), "my favorite color is green" )
2348
2374
})
2349
2375
0 commit comments