bitbake: bitbake-setup: add support for specifying branches in repo checkouts

Previously bitbake-setup was checking out 'detached commits' using
fetcher's nobranch feature, as that is the only option when only a revision is in the config.

Branches are optional, but beneficial, as

- checkout directory will be on a branch, making it easier for users
to understand where they are if they need to make changes (also
bitbake will print branch information instead of saying 'HEAD:sha').

- supply chain security! Enforcing a branch means any specified revision
has to be on it, and no one can sneak in (accidentally or deliberately!)
some dangling commit, or something from their private branch in the same repo.

(Bitbake rev: 45ed9b9faebdaa8cb7cc8dd2a6d51ec8eea06e73)

Signed-off-by: Alexander Kanavin <alex@linutronix.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Alexander Kanavin 2025-09-29 14:56:15 +02:00 committed by Richard Purdie
parent dd358f75f4
commit 1a55c45617
4 changed files with 23 additions and 7 deletions

View File

@ -86,13 +86,17 @@ def checkout_layers(layers, layerdir, d):
r_remote = r_data['git-remote']
rev = r_remote['rev']
branch = r_remote.get('branch', None)
remotes = r_remote['remotes']
for remote in remotes:
type,host,path,user,pswd,params = bb.fetch.decodeurl(remotes[remote]["uri"])
fetchuri = bb.fetch.encodeurl(('git',host,path,user,pswd,params))
print(" {}".format(r_name))
fetcher = bb.fetch.Fetch(["{};protocol={};rev={};nobranch=1;destsuffix={}".format(fetchuri,type,rev,repodir)], d)
if branch:
fetcher = bb.fetch.Fetch(["{};protocol={};rev={};branch={};destsuffix={}".format(fetchuri,type,rev,branch,repodir)], d)
else:
fetcher = bb.fetch.Fetch(["{};protocol={};rev={};nobranch=1;destsuffix={}".format(fetchuri,type,rev,repodir)], d)
do_fetch(fetcher, layerdir)
if os.path.exists(os.path.join(layerdir, repodir, 'scripts/oe-setup-build')):
@ -444,12 +448,16 @@ def are_layers_changed(layers, layerdir, d):
r_remote = r_data['git-remote']
rev = r_remote['rev']
branch = r_remote.get('branch', None)
remotes = r_remote['remotes']
for remote in remotes:
type,host,path,user,pswd,params = bb.fetch.decodeurl(remotes[remote]["uri"])
fetchuri = bb.fetch.encodeurl(('git',host,path,user,pswd,params))
fetcher = bb.fetch.FetchData("{};protocol={};rev={};nobranch=1;destsuffix={}".format(fetchuri,type,rev,repodir), d)
if branch:
fetcher = bb.fetch.FetchData("{};protocol={};rev={};branch={};destsuffix={}".format(fetchuri,type,rev,branch,repodir), d)
else:
fetcher = bb.fetch.FetchData("{};protocol={};rev={};nobranch=1;destsuffix={}".format(fetchuri,type,rev,repodir), d)
upstream_revision = fetcher.method.latest_revision(fetcher, d, 'default')
rev_parse_result = bb.process.run('git -C {} rev-parse HEAD'.format(os.path.join(layerdir, repodir)))
local_revision = rev_parse_result[0].strip()

View File

@ -8,6 +8,7 @@
"uri": "git://git.openembedded.org/bitbake;protocol=https"
}
},
"branch": "master",
"rev": "master"
},
"path": "bitbake"
@ -19,6 +20,7 @@
"uri": "git://git.openembedded.org/openembedded-core;protocol=https"
}
},
"branch": "master",
"rev": "master"
},
"path": "openembedded-core"
@ -30,6 +32,7 @@
"uri": "git://git.yoctoproject.org/yocto-docs;protocol=https"
}
},
"branch": "master",
"rev": "master"
},
"path": "yocto-docs"

View File

@ -8,6 +8,7 @@
"uri": "git://git.openembedded.org/bitbake;protocol=https"
}
},
"branch": "master",
"rev": "master"
},
"path": "bitbake"
@ -19,6 +20,7 @@
"uri": "git://git.openembedded.org/openembedded-core;protocol=https"
}
},
"branch": "master",
"rev": "master"
},
"path": "openembedded-core"
@ -30,6 +32,7 @@
"uri": "git://git.yoctoproject.org/meta-yocto;protocol=https"
}
},
"branch": "master",
"rev": "master"
},
"path": "meta-yocto"
@ -41,6 +44,7 @@
"uri": "git://git.yoctoproject.org/yocto-docs;protocol=https"
}
},
"branch": "master",
"rev": "master"
},
"path": "yocto-docs"

View File

@ -87,7 +87,7 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
bbsetup = os.path.abspath(os.path.dirname(__file__) + "/../../../bin/bitbake-setup")
return bb.process.run("{} --global-settings {} {}".format(bbsetup, os.path.join(self.tempdir, 'global-config'), cmd))
def add_json_config_to_registry(self, name, rev):
def add_json_config_to_registry(self, name, rev, branch):
config = """
{
"sources": {
@ -98,6 +98,7 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
"uri": "file://%s"
}
},
"branch": "%s",
"rev": "%s"
},
"path": "test-repo"
@ -134,7 +135,7 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
},
"version": "1.0"
}
""" % (self.testrepopath, rev)
""" % (self.testrepopath, branch, rev)
os.makedirs(os.path.join(self.registrypath, os.path.dirname(name)), exist_ok=True)
with open(os.path.join(self.registrypath, name), 'w') as f:
f.write(config)
@ -208,12 +209,12 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
self.assertNotIn("test-config-1", out[0])
self.assertNotIn("test-config-2", out[0])
json_1 = self.add_json_config_to_registry('test-config-1.conf.json', 'master')
json_1 = self.add_json_config_to_registry('test-config-1.conf.json', 'master', 'master')
out = self.runbbsetup("list")
self.assertIn("test-config-1", out[0])
self.assertNotIn("test-config-2", out[0])
json_2 = self.add_json_config_to_registry('config-2/test-config-2.conf.json', 'master')
json_2 = self.add_json_config_to_registry('config-2/test-config-2.conf.json', 'master', 'master')
out = self.runbbsetup("list --write-json={}".format(os.path.join(self.tempdir, "test-configs.json")))
self.assertIn("test-config-1", out[0])
self.assertIn("test-config-2", out[0])
@ -270,7 +271,7 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
branch = "another-branch"
self.git('checkout -b {}'.format(branch), cwd=self.testrepopath)
self.add_file_to_testrepo('test-file', test_file_content)
json_1 = self.add_json_config_to_registry('test-config-1.conf.json', branch)
json_1 = self.add_json_config_to_registry('test-config-1.conf.json', branch, branch)
for c in ('gadget','gizmo','gadget-notemplate','gizmo-notemplate'):
buildpath = os.path.join(self.tempdir, 'bitbake-builds', 'test-config-1-{}'.format(c))
os.environ['BBPATH'] = os.path.join(buildpath, 'build')