Commit 84f9541e authored by Jérome Perrin's avatar Jérome Perrin

gitclone: refuse git checkout on a branch when allow-picked-versions is false

Because the we set allow-picked-versions to false in order to ensure
build reproductibility, it makes sense to also enforce code checked out
from git is checked out at a fixed revision
parent 45bf74d8
...@@ -450,6 +450,19 @@ boolean option:: ...@@ -450,6 +450,19 @@ boolean option::
repository = https://example.net/example.git/ repository = https://example.net/example.git/
ignore-ssl-certificate = true ignore-ssl-certificate = true
Reproductible builds
~~~~~~~~~~~~~~~~~~~~
buildout's `allow-picked-versions` version can be set to false to prevent
buildout from picking the latest version of eggs. This options is usually set
to false in production deployments, to ensure that the buildout will be
reproductible because every dependencies have been pinned to a specific version.
`slapos.recipe.build:gitclone` follows the same logic, when buildout does not
allow picked version, `slapos.recipe.build:gitclone` will not allow to clone
from a `branch`, but only from a fixed `revision`.
Other options Other options
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
......
...@@ -52,6 +52,7 @@ class GitCloneNonInformativeTests(unittest.TestCase): ...@@ -52,6 +52,7 @@ class GitCloneNonInformativeTests(unittest.TestCase):
'buildout': { 'buildout': {
'parts-directory': self.parts_directory_path, 'parts-directory': self.parts_directory_path,
'directory': self.dir, 'directory': self.dir,
'allow-picked-versions': 'true',
} }
} }
default_options = { default_options = {
...@@ -111,6 +112,7 @@ class GitCloneNonInformativeTests(unittest.TestCase): ...@@ -111,6 +112,7 @@ class GitCloneNonInformativeTests(unittest.TestCase):
'buildout': { 'buildout': {
'parts-directory': self.parts_directory_path, 'parts-directory': self.parts_directory_path,
'directory': self.dir, 'directory': self.dir,
'allow-picked-versions': 'true',
} }
} }
options = { options = {
...@@ -136,6 +138,29 @@ class GitCloneNonInformativeTests(unittest.TestCase): ...@@ -136,6 +138,29 @@ class GitCloneNonInformativeTests(unittest.TestCase):
def test_ignore_ssl_certificate_false(self): def test_ignore_ssl_certificate_false(self):
self.test_ignore_ssl_certificate(ignore_ssl_certificate=False) self.test_ignore_ssl_certificate(ignore_ssl_certificate=False)
def test_allow_picked_versions(self):
import slapos.recipe.gitclone
bo = {
'buildout': {
'parts-directory': self.parts_directory_path,
'directory': self.dir,
'allow-picked-versions': 'false',
}
}
with self.assertRaises(zc.buildout.UserError):
slapos.recipe.gitclone.Recipe(
bo,
'test',
{ 'repository': GIT_REPOSITORY,
'branch': 'master' })
# with a revision, no problem
recipe = slapos.recipe.gitclone.Recipe(
bo,
'test',
{ 'repository': GIT_REPOSITORY,
'revision': REVISION })
recipe.install()
def test_suite(): def test_suite():
suite = unittest.TestSuite(( suite = unittest.TestSuite((
doctest.DocFileSuite( doctest.DocFileSuite(
......
...@@ -164,6 +164,9 @@ class Recipe(object): ...@@ -164,6 +164,9 @@ class Recipe(object):
if not os.path.exists(self.location): if not os.path.exists(self.location):
self.update = self.install self.update = self.install
if not self.revision and not buildout['buildout']['allow-picked-versions'].lower() in TRUE_VALUES:
raise UserError('Revision must be specified when buildout runs with allow-picking-versions set to false')
def gitReset(self, revision=None): def gitReset(self, revision=None):
"""Operates git reset on the repository.""" """Operates git reset on the repository."""
command = [self.git_command, 'reset', '--hard'] command = [self.git_command, 'reset', '--hard']
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment