@@ -194,8 +194,15 @@ var _ = Describe("Carvel Baker", func() {
194194 Expect (filepath .Join (outputPath , "icon.png" )).To (BeAnExistingFile ())
195195 Expect (filepath .Join (outputPath , "version" )).To (BeAnExistingFile ())
196196 })
197- It ("Generates a bosh release tarball" , func () {
198- Expect (filepath .Join (outputPath , "releases" , "k8s-tile-test-0.1.1.tgz" )).To (BeAnExistingFile ())
197+ It ("generates a bosh release tarball with fingerprinted version" , func () {
198+ releaseVersion := subject .GetReleaseVersion ()
199+ Expect (releaseVersion ).To (HavePrefix ("0.1.1+" ))
200+ Expect (releaseVersion ).To (MatchRegexp (`^0\.1\.1\+[0-9a-f]{12}$` ))
201+ Expect (filepath .Join (outputPath , "releases" , "k8s-tile-test-" + releaseVersion + ".tgz" )).To (BeAnExistingFile ())
202+
203+ tarball , err := subject .GetReleaseTarball ()
204+ Expect (err ).NotTo (HaveOccurred ())
205+ Expect (tarball ).To (ContainSubstring (releaseVersion ))
199206 })
200207 It ("does not generate a separate package-install job" , func () {
201208 Expect (filepath .Join (boshReleasePath , "jobs" , "package-install" )).NotTo (BeADirectory ())
@@ -347,9 +354,11 @@ var _ = Describe("Carvel Baker", func() {
347354 err = copyTestFile (tarball , cachedTarball )
348355 Expect (err ).NotTo (HaveOccurred ())
349356
357+ uploadReleaseVersion := subject .GetReleaseVersion ()
358+
350359 releaseLock := cargo.BOSHReleaseTarballLock {
351360 Name : "k8s-tile-test" ,
352- Version : "0.1.1" ,
361+ Version : uploadReleaseVersion ,
353362 }
354363
355364 subject2 := NewBaker ()
@@ -359,8 +368,9 @@ var _ = Describe("Carvel Baker", func() {
359368
360369 outputPath := path .Join (inputPath , ".carvel-tile" )
361370 Expect (filepath .Join (outputPath , "base.yml" )).To (BeAnExistingFile ())
362- Expect (filepath .Join (outputPath , "releases" , "k8s-tile-test-0.1.1 .tgz" )).To (BeAnExistingFile ())
371+ Expect (filepath .Join (outputPath , "releases" , "k8s-tile-test-" + uploadReleaseVersion + " .tgz" )).To (BeAnExistingFile ())
363372 Expect (filepath .Join (outputPath , "runtime_configs" )).To (BeADirectory ())
373+ Expect (subject2 .GetReleaseVersion ()).To (Equal (uploadReleaseVersion ))
364374 })
365375 })
366376
@@ -436,7 +446,7 @@ var _ = Describe("Carvel Baker", func() {
436446
437447 releaseLock := cargo.BOSHReleaseTarballLock {
438448 Name : "k8s-tile-test" ,
439- Version : "0.1.1" ,
449+ Version : uploadBaker . GetReleaseVersion () ,
440450 }
441451
442452 publishBaker := NewBaker ()
@@ -466,6 +476,99 @@ var _ = Describe("Carvel Baker", func() {
466476 })
467477 })
468478
479+ Context ("hashBoshReleaseInputs" , func () {
480+ It ("is deterministic" , func () {
481+ dir , err := os .MkdirTemp ("" , "hash-test-*" )
482+ Expect (err ).NotTo (HaveOccurred ())
483+ defer func () { _ = os .RemoveAll (dir ) }()
484+
485+ Expect (os .WriteFile (filepath .Join (dir , "a.txt" ), []byte ("hello" ), 0644 )).To (Succeed ())
486+ Expect (os .MkdirAll (filepath .Join (dir , "sub" ), 0755 )).To (Succeed ())
487+ Expect (os .WriteFile (filepath .Join (dir , "sub" , "b.txt" ), []byte ("world" ), 0644 )).To (Succeed ())
488+
489+ h1 , err := hashBoshReleaseInputs (dir )
490+ Expect (err ).NotTo (HaveOccurred ())
491+ h2 , err := hashBoshReleaseInputs (dir )
492+ Expect (err ).NotTo (HaveOccurred ())
493+
494+ Expect (h1 ).To (Equal (h2 ))
495+ Expect (h1 ).To (HaveLen (12 ))
496+ })
497+
498+ It ("changes when file contents change" , func () {
499+ dir , err := os .MkdirTemp ("" , "hash-test-*" )
500+ Expect (err ).NotTo (HaveOccurred ())
501+ defer func () { _ = os .RemoveAll (dir ) }()
502+
503+ Expect (os .WriteFile (filepath .Join (dir , "a.txt" ), []byte ("hello" ), 0644 )).To (Succeed ())
504+
505+ h1 , err := hashBoshReleaseInputs (dir )
506+ Expect (err ).NotTo (HaveOccurred ())
507+
508+ Expect (os .WriteFile (filepath .Join (dir , "a.txt" ), []byte ("changed" ), 0644 )).To (Succeed ())
509+
510+ h2 , err := hashBoshReleaseInputs (dir )
511+ Expect (err ).NotTo (HaveOccurred ())
512+
513+ Expect (h1 ).NotTo (Equal (h2 ))
514+ })
515+
516+ It ("changes when a file is renamed" , func () {
517+ dir , err := os .MkdirTemp ("" , "hash-test-*" )
518+ Expect (err ).NotTo (HaveOccurred ())
519+ defer func () { _ = os .RemoveAll (dir ) }()
520+
521+ Expect (os .WriteFile (filepath .Join (dir , "a.txt" ), []byte ("hello" ), 0644 )).To (Succeed ())
522+
523+ h1 , err := hashBoshReleaseInputs (dir )
524+ Expect (err ).NotTo (HaveOccurred ())
525+
526+ Expect (os .Rename (filepath .Join (dir , "a.txt" ), filepath .Join (dir , "b.txt" ))).To (Succeed ())
527+
528+ h2 , err := hashBoshReleaseInputs (dir )
529+ Expect (err ).NotTo (HaveOccurred ())
530+
531+ Expect (h1 ).NotTo (Equal (h2 ))
532+ })
533+
534+ It ("excludes .git directory" , func () {
535+ dir , err := os .MkdirTemp ("" , "hash-test-*" )
536+ Expect (err ).NotTo (HaveOccurred ())
537+ defer func () { _ = os .RemoveAll (dir ) }()
538+
539+ Expect (os .WriteFile (filepath .Join (dir , "a.txt" ), []byte ("hello" ), 0644 )).To (Succeed ())
540+ Expect (os .MkdirAll (filepath .Join (dir , ".git" , "objects" ), 0755 )).To (Succeed ())
541+ Expect (os .WriteFile (filepath .Join (dir , ".git" , "HEAD" ), []byte ("ref: refs/heads/main" ), 0644 )).To (Succeed ())
542+
543+ h1 , err := hashBoshReleaseInputs (dir )
544+ Expect (err ).NotTo (HaveOccurred ())
545+
546+ Expect (os .WriteFile (filepath .Join (dir , ".git" , "HEAD" ), []byte ("ref: refs/heads/other" ), 0644 )).To (Succeed ())
547+
548+ h2 , err := hashBoshReleaseInputs (dir )
549+ Expect (err ).NotTo (HaveOccurred ())
550+
551+ Expect (h1 ).To (Equal (h2 ))
552+ })
553+ })
554+
555+ Context ("buildReleaseVersion" , func () {
556+ It ("appends fingerprint with + separator" , func () {
557+ Expect (buildReleaseVersion ("10.4.0" , "a1b2c3d4e5f6" )).To (Equal ("10.4.0+a1b2c3d4e5f6" ))
558+ })
559+
560+ It ("appends fingerprint with . separator when version already contains +" , func () {
561+ Expect (buildReleaseVersion ("10.4.0+beta.1" , "a1b2c3d4e5f6" )).To (Equal ("10.4.0+beta.1.a1b2c3d4e5f6" ))
562+ })
563+ })
564+
565+ Context ("GetReleaseVersion" , func () {
566+ It ("returns empty string before Bake is called" , func () {
567+ subject := NewBaker ()
568+ Expect (subject .GetReleaseVersion ()).To (BeEmpty ())
569+ })
570+ })
571+
469572 Context ("generateManifestTemplate with different entry names" , func () {
470573 It ("parameterizes the entry name throughout the template" , func () {
471574 template := generateManifestTemplate ("my-custom-pkg" )
0 commit comments