Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
gitlab-ci
Manage
Activity
Members
Labels
Plan
Jira
Code
Merge requests
5
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
SECO Northern Europe
Yocto
infrastructure
gitlab-ci
Commits
2ae874f9
Commit
2ae874f9
authored
3 years ago
by
Jonas Höppner
Browse files
Options
Downloads
Patches
Plain Diff
CI: Reuse existing integration branch if submodule is already on new revision
parent
3318487d
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
common.py
+1
-0
1 addition, 0 deletions
common.py
deploy_gitlab_ci.py
+17
-6
17 additions, 6 deletions
deploy_gitlab_ci.py
update_submodule.py
+72
-21
72 additions, 21 deletions
update_submodule.py
with
90 additions
and
27 deletions
common.py
+
1
−
0
View file @
2ae874f9
...
@@ -239,6 +239,7 @@ def clone_project(project: Project, into, branch=None):
...
@@ -239,6 +239,7 @@ def clone_project(project: Project, into, branch=None):
def
get_repository_file_raw
(
project
:
Project
,
filename
,
ref
=
None
):
def
get_repository_file_raw
(
project
:
Project
,
filename
,
ref
=
None
):
# TODO tree objects are not supported
# TODO tree objects are not supported
fileobj
=
get_repository_file_obj
(
project
,
filename
,
ref
)
fileobj
=
get_repository_file_obj
(
project
,
filename
,
ref
)
logging
.
debug
(
"
Read file
'
%s
'
from
'
%s
'
at ref %s
"
,
filename
,
project
.
name
,
ref
)
return
project
.
repository_raw_blob
(
return
project
.
repository_raw_blob
(
fileobj
[
"
id
"
],
retry_transient_errors
=
True
fileobj
[
"
id
"
],
retry_transient_errors
=
True
).
decode
()
).
decode
()
...
...
This diff is collapsed.
Click to expand it.
deploy_gitlab_ci.py
+
17
−
6
View file @
2ae874f9
...
@@ -40,7 +40,13 @@ def read_keys_from_gitlab_ci_yml(gitlab_ci_yml):
...
@@ -40,7 +40,13 @@ def read_keys_from_gitlab_ci_yml(gitlab_ci_yml):
def
integrate_submodule_into
(
def
integrate_submodule_into
(
gitlab
,
project_name
,
submodule_name
,
new_revision
,
branch
,
commit_and_push
=
True
gitlab
,
project_name
,
submodule_name
,
new_revision
,
branch
,
commit_and_push
=
True
,
force_replace_of_existing_branch
=
False
,
):
):
gitlab_project
=
common
.
get_project
(
gitlab
,
project_name
)
gitlab_project
=
common
.
get_project
(
gitlab
,
project_name
)
...
@@ -56,6 +62,7 @@ def integrate_submodule_into(
...
@@ -56,6 +62,7 @@ def integrate_submodule_into(
new_revision
,
new_revision
,
branch
,
branch
,
commit_and_push
=
commit_and_push
,
commit_and_push
=
commit_and_push
,
force_replace_of_existing_branch
=
force_replace_of_existing_branch
,
)
)
if
integration_branch_name
is
None
:
if
integration_branch_name
is
None
:
return
None
return
None
...
@@ -196,6 +203,11 @@ def main():
...
@@ -196,6 +203,11 @@ def main():
args
.
revision
,
args
.
revision
,
args
.
branch
,
args
.
branch
,
commit_and_push
=
False
,
commit_and_push
=
False
,
# We need the checkout and integration
# branch in the manifest commit
# TODO develop a way to allow amend to
# this branch also
force_replace_of_existing_branch
=
True
,
)
)
if
manifest_project
is
not
None
:
if
manifest_project
is
not
None
:
project_integration
[
args
.
project
]
=
manifest_project
project_integration
[
args
.
project
]
=
manifest_project
...
@@ -292,12 +304,11 @@ def main():
...
@@ -292,12 +304,11 @@ def main():
continue
continue
# get BB_RECIPE_NAME from the projects .gitlab-ci.yml
# get BB_RECIPE_NAME from the projects .gitlab-ci.yml
gitlab_ci_yml_file
=
os
.
path
.
join
(
# Use direct read from gitlab as we have not checked out
integration
[
"
repo
"
].
working_tree_dir
,
"
.gitlab-ci.yml
"
# the repo if the branch is already up to date
gitlab_ci_yml
=
common
.
get_repository_file_raw
(
integration
[
"
project
"
],
"
.gitlab-ci.yml
"
,
ref
=
integration
[
"
branch
"
]
)
)
logging
.
debug
(
"
Read recipe name from %s
"
,
gitlab_ci_yml_file
)
with
open
(
gitlab_ci_yml_file
,
"
r
"
,
encoding
=
"
utf8
"
)
as
fp
:
gitlab_ci_yml
=
fp
.
read
()
project_keys
=
read_keys_from_gitlab_ci_yml
(
gitlab_ci_yml
)
project_keys
=
read_keys_from_gitlab_ci_yml
(
gitlab_ci_yml
)
new_srcrev
=
update_srcrev
(
new_srcrev
=
update_srcrev
(
...
...
This diff is collapsed.
Click to expand it.
update_submodule.py
+
72
−
21
View file @
2ae874f9
...
@@ -9,7 +9,7 @@ import tempfile
...
@@ -9,7 +9,7 @@ import tempfile
from
configparser
import
ConfigParser
from
configparser
import
ConfigParser
from
furl
import
furl
from
furl
import
furl
from
git
import
GitCommandError
,
Repo
from
git
import
GitCommandError
,
Repo
from
gitlab
import
Gitlab
from
gitlab
import
Gitlab
,
GitlabGetError
from
gitlab.v4.objects
import
Project
from
gitlab.v4.objects
import
Project
from
ruamel.yaml
import
YAML
from
ruamel.yaml
import
YAML
...
@@ -21,7 +21,7 @@ def get_submodule_project_path_and_revision(project: Project, submodule, branch=
...
@@ -21,7 +21,7 @@ def get_submodule_project_path_and_revision(project: Project, submodule, branch=
logging
.
error
(
"
Submodule %s not found in %s.
"
,
submodule
,
project
.
name
)
logging
.
error
(
"
Submodule %s not found in %s.
"
,
submodule
,
project
.
name
)
return
None
,
None
return
None
,
None
logging
.
debug
(
"
Gitmodules: %s
"
,
gitmodules
)
#
logging.debug("Gitmodules: %s", gitmodules)
cfgparse
=
ConfigParser
()
cfgparse
=
ConfigParser
()
cfgparse
.
read_string
(
gitmodules
)
cfgparse
.
read_string
(
gitmodules
)
...
@@ -181,6 +181,7 @@ def update_submodule_and_include_ref(
...
@@ -181,6 +181,7 @@ def update_submodule_and_include_ref(
new_revision
,
new_revision
,
branch
=
None
,
branch
=
None
,
commit_and_push
=
True
,
commit_and_push
=
True
,
force_replace_of_existing_branch
=
False
,
):
):
"""
Update the submodule and include refs to the submodule in the given project.
"""
Update the submodule and include refs to the submodule in the given project.
Create mergerequest if needed.
Create mergerequest if needed.
...
@@ -198,23 +199,24 @@ def update_submodule_and_include_ref(
...
@@ -198,23 +199,24 @@ def update_submodule_and_include_ref(
integration_commit (hexsha): Hash of the newly created commit
integration_commit (hexsha): Hash of the newly created commit
message: Commit message based on the integrated changes.
message: Commit message based on the integrated changes.
"""
"""
gitlab
=
project
.
manager
.
gitlab
if
branch
is
None
:
if
branch
is
None
:
branch
=
project
.
default_branch
branch
=
project
.
default_branch
logging
.
debug
(
"
Branch: %s
"
,
branch
)
logging
.
debug
(
"
Branch: %s
"
,
branch
)
_
,
submodule_current_rev
=
get_submodule_project_path_and_revision
(
(
project
,
submodule_name
,
branch
submodule_project_path
,
)
submodule_current_rev
,
)
=
get_submodule_project_path_and_revision
(
project
,
submodule_name
,
branch
)
# Check if revisions are different
# Check if revisions are different
if
submodule_current_rev
==
new_revision
:
if
submodule_current_rev
==
new_revision
and
not
force_replace_of_existing_branch
:
print
(
"
Submodule is already at %s
"
%
new_revision
)
print
(
"
Submodule is already at %s
"
%
new_revision
)
return
(
None
,
None
,
None
,
None
)
return
(
None
,
None
,
None
,
None
)
project_repo
,
submodule_project
=
clone_project_and_submodule
(
# Get submodule project
project
,
submodule_name
,
branch
submodule_project
=
common
.
get_project
(
gitlab
,
submodule_project_path
)
)
# Get commits between current and new revision
# Get commits between current and new revision
revision_range
=
submodule_current_rev
+
"
..
"
+
new_revision
revision_range
=
submodule_current_rev
+
"
..
"
+
new_revision
...
@@ -235,12 +237,70 @@ def update_submodule_and_include_ref(
...
@@ -235,12 +237,70 @@ def update_submodule_and_include_ref(
break
break
logging
.
debug
(
"
Integration branch suffix: %s
"
,
integration_branch_suffix
)
logging
.
debug
(
"
Integration branch suffix: %s
"
,
integration_branch_suffix
)
#
Setup
integration branch
#
Construct
integration branch
name
integration_branch_name
=
common
.
integration_branch_name
(
integration_branch_name
=
common
.
integration_branch_name
(
submodule_project
.
name
,
integration_branch_suffix
submodule_project
.
name
,
integration_branch_suffix
)
)
# Create integration branch
print
(
"
Creating/replacing integration branch %s
"
%
integration_branch_name
)
# Construct commit message
message
=
"
Integrate %s/%s%s
\n
%s
"
%
(
submodule_project
.
name
,
integration_branch_suffix
,
"
and %d more
"
%
(
len
(
commits
)
-
1
)
if
len
(
commits
)
>
1
else
""
,
common
.
list_commits
(
commits
),
)
# Check if we already have an integration branch (before we actually do the checkout)
# Check if integration branch already exists and if it is up to date
# This is needed for one use case:
# It is possible to amend changes to the integration branch manually
# outside the pipeline.
# When the submodule revision has not changed and the pipeline is run
# again (due to merge or manually triggered) the manual change persists
# in the final commit
# For example rename a file in gitlab-ci repo that is included in a
# subproject, requires an adapted include statement here.
# To get this change 'atomic' the updated include statement should be
# in the same commit as the update of the submodule
existing_branch
=
None
if
not
force_replace_of_existing_branch
:
try
:
existing_branch
=
project
.
branches
.
get
(
integration_branch_name
)
except
GitlabGetError
:
# Branch not found
pass
if
existing_branch
:
(
_
,
integration_branch_submodule_rev
,
)
=
get_submodule_project_path_and_revision
(
project
,
submodule_name
,
integration_branch_name
)
logging
.
debug
(
"
Revision in integration branch
'
%s
'
, new_revision
'
%s
'"
,
integration_branch_submodule_rev
,
new_revision
)
if
integration_branch_submodule_rev
==
new_revision
:
print
(
"
Submodule is already at %s on branch %s
"
%
(
new_revision
,
integration_branch_name
)
)
integration_commit
=
existing_branch
.
commit
[
"
id
"
]
return
None
,
integration_branch_name
,
integration_commit
,
message
# Clone the project, we need to do changes
project_repo
,
submodule_project
=
clone_project_and_submodule
(
project
,
submodule_name
,
branch
)
if
existing_branch
:
print
(
"
Replacing outdated integration branch %s
"
%
integration_branch_name
)
else
:
print
(
"
Creating integration branch %s
"
%
integration_branch_name
)
# Create branch
project_repo
.
head
.
set_reference
(
project_repo
.
create_head
(
integration_branch_name
))
project_repo
.
head
.
set_reference
(
project_repo
.
create_head
(
integration_branch_name
))
# Update submodule to new revision
# Update submodule to new revision
...
@@ -269,18 +329,9 @@ def update_submodule_and_include_ref(
...
@@ -269,18 +329,9 @@ def update_submodule_and_include_ref(
fp
.
write
(
new_gitlab_ci_yml
)
fp
.
write
(
new_gitlab_ci_yml
)
project_repo
.
git
.
add
(
os
.
path
.
basename
(
gitlab_ci_yml_filename
))
project_repo
.
git
.
add
(
os
.
path
.
basename
(
gitlab_ci_yml_filename
))
# Construct commit message and commit the change
message
=
"
Integrate %s/%s%s
\n
%s
"
%
(
submodule_project
.
name
,
integration_branch_suffix
,
"
and %d more
"
%
(
len
(
commits
)
-
1
)
if
len
(
commits
)
>
1
else
""
,
common
.
list_commits
(
commits
),
)
# Commit the changes
# Commit the changes
if
commit_and_push
:
if
commit_and_push
:
# Make an API request to create the gitlab.user object
# Make an API request to create the gitlab.user object
gitlab
=
project
.
manager
.
gitlab
gitlab
.
auth
()
gitlab
.
auth
()
integration_commit
=
common
.
commit_and_push
(
integration_commit
=
common
.
commit_and_push
(
project
,
project
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment