The merger starts every operation by resetting the repository.
That means clearing out any failed previous merges and updating
and restoring the branch state to match the upstream origin
repo.
For repos with a very large number of branches (10k), this can take
some time (minutes). This is mostly due to the inefficiency of
looking up the origin ref one at a time (gitpython reads the
packed-refs file for each lookup, ironically negating the benefit
of packed-refs). To bypass this, use our previously developed
method for getting all the refs efficiently and do that once at
the start of the reset method.
Change-Id: If21245cd562c6499378c4f3353332d87c4ca4b47
Since squash merges will not create a merge commit Zuul is creating one
separately. However, this step can fail when there are no changes to
commit. This might for example happen in change-triggered post
pipelines.
To fix this issue we will restore the behavior used prior to
I3379b19d77badbe2a2ec8347ddacc50a2551e505 and allow creating empty
merge commits.
Change-Id: Ic18cb98f12260338799e963b8dc915c8be1d421b
Zuul packs refs directly rather than rely on git to do so. The reason
for this is it greatly speeds up repo resetting. Typically there are two
pieces of information for each packged ref (sha and refname). Git
annotated and signed tags are special because they have the sha of the
tag object proper, the tag refname, and finally the sha of the object
the tag refers to.
Update Zuul's ref packing to handle this extra piece of information for
git tags.
Co-Authored-By: James E. Blair <jim@acmegating.com>
Change-Id: I828ab924a918e3ded2cd64deadf8ad0b4726eb1e
In addition to the safeguard in
Iebf49a9efe193788199197bf7846e336d96edf19 we will only return the final
config for a project-branch as part of the merge result.
Change-Id: I1eb3b75d8762aff4e1ebd057661869df985a79e2
Use a fixed timestamp and merge message so that zuul mergers
produce the exact same commit sha each time they perform a merge
for a queue item. This can help correlate git repo states for
different jobs in the same change as well as across different
changes in the case of a dependent change series.
The timestamp used is the "configuration time" of the queue item
(ie, the time the buildset was created or reset). This means
that it will change on gate resets (which could be useful for
distinguishing one run of a build from another).
Change-Id: I3379b19d77badbe2a2ec8347ddacc50a2551e505
When refs are set asynchronously we don't supply a logger and expect the
`_setRefs()` to return the log messages. This was not the case in the
exception handler when we can't resolve an object.
In addition to this fix another debug message is now also return as part
of the message list as expected.
Traceback (most recent call last):
File "/opt/zuul/lib/python3.11/site-packages/zuul/merger/merger.py", line 553, in _setRefs
repo.odb.info(binsha)
File "/opt/zuul/lib/python3.11/site-packages/git/db.py", line 40, in info
hexsha, typename, size = self._git.get_object_header(bin_to_hex(binsha))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/zuul/lib/python3.11/site-packages/git/cmd.py", line 1384, in get_object_header
return self.__get_object_header(cmd, ref)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/zuul/lib/python3.11/site-packages/git/cmd.py", line 1371, in __get_object_header
return self._parse_object_header(cmd.stdout.readline())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/zuul/lib/python3.11/site-packages/git/cmd.py", line 1332, in _parse_object_header
raise ValueError("SHA %s could not be resolved, git returned: %r" % (tokens[0], header_line.strip()))
ValueError: SHA b'8683bca8c75c1c3ae07730452d93c736b1e899db' could not be resolved, git returned: b'8683bca8c75c1c3ae07730452d93c736b1e899db missing'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/concurrent/futures/process.py", line 261, in _process_worker
r = call_item.fn(*call_item.args, **call_item.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/zuul/lib/python3.11/site-packages/zuul/merger/merger.py", line 532, in setRefsAsync
messages = Repo._setRefs(repo, refs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/zuul/lib/python3.11/site-packages/zuul/merger/merger.py", line 560, in _setRefs
log.warning("Unable to resolve reference %s at %s in %s",
^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'warning'
Change-Id: Ieb54a53f1fe09848da0a40fdb0dfcb445c65eded
When a repo that is being used for a zuul role has override-checkout
set to a tag, the job would fail because we did not reconstruct the
tag in our zuul-role checkout; we only did that for branches.
This fixes the repo state restore for any type of ref.
There is a an untested code path where a zuul role repo is checked
out to a tag using override-checkout. Add a test for that (and
also the same for a branch, for good measure).
Change-Id: I36f142cd3c4e7d0b930318dddd7276f3635cc3a2
The recent update to make setting refs more efficient could encounter
an edge case if a branch or tag was removed from the upstream repo
after the repo state was retrieved by zuul. If removing the ref caused
the underlying objects to be removed not not be sent in a fetch, then
our blindly setting the repo state with a ref pointed to an unresolvable
object could leave the repository in a corrupted state.
To recover from any potential corruption that may have somehow happened,
this change adds an additional case where we will remove the underlying
repo and re-clone.
To prevent any such corruption from happening in the first place, we add
a check that each hexsha is resolvable before we set it when restoring
the repo state. This does add a small amount of overhead, but should be
much less than manipulating the loos refs one at a time. A copy of nova
with 10,000 refs adds 100ms for this checking.
Change-Id: Ifd298905e634f83a147644d35ff3ea1c143b3d1f
When the executor clones a repo from the cache to the workspace,
it performs a lot of unecessary work:
* It checks out HEAD and prepares a workspace which we will
immediately change.
* It copies all of the branch refs, half of which we will immediately
delete, and in some configurations (exclude_unprotected_branches)
we will immediately delete most of the rest. Deleting refs with
gitpython is much more expensive than creating them.
This change updates the initial clone to do none of those, instead
relying on the repo state restoration to take care of that for us.
Change-Id: Ie8846c48ccd6255953f46640f5559bb41491d425
Starting with Github Enterprise 3.8[0] and github.com from September
2022 on[1], the merge strategy changed from using merge-recursive to
merge-ort[0].
The merge-ort strategy is available in the Git client since version
2.33.0 and became the default in 2.34.0[2].
If not configured otherwise, we've so far used the default merge
strategy of the Git client (which varies depending on the client
version). With this change, we are now explicitly choosing the default
merge strategy based on the Github version. This way, we can reduce
errors resulting from the use of different merge strategies in Zuul and
Github.
Since the newly added merge strategies must be understood by the mergers
we also need to bump the model API version.
[0] https://docs.github.com/en/enterprise-server@3.8/admin/release-notes
[1] https://github.blog/changelog/2022-09-12-merge-commits-now-created-using-the-merge-ort-strategy/
[2] https://git-scm.com/docs/merge-strategies#Documentation/merge-strategies.txt-recursive
Change-Id: I354a76fa8985426312344818320980c67171d774
The Github driver prints un-sanitized URLs to log files. This PR
uses the redact_url function to sanitize the remote URL before
logging.
Task: #48344
Signed-off-by: Flavio Percoco <flavio@pacerevenue.com>
Change-Id: Id725c8dfe3e4e782c293ff350fc7e35b23d377ab
Signed-off-by: Flavio Percoco <flavio@pacerevenue.com>
From the previous log messages related to a cat job it wasn't clear
which HEAD SHA was used to get the file content.
This change adds a log message to the `getFiles()` method that contains
the HEAD commit SHA.
Change-Id: I02a3a97f9b3dfa70f6e55954ea6ef365289f0046
In normal git usage, cherry-picking a commit that has already been
applied and doesn't do anything or cherry-picking an empty commit causes
git to exit with an error to let the user decide what they want to do.
However, this doesn't match the behavior of merges and rebases where
non-empty commits that have already been applied are simply skipped
(empty source commits are preserved).
To fix this, add the --keep-redundant-commit option to `git cherry-pick`
to make git always keep a commit when cherry-picking even when it is
empty for either reason. Then, after the cherry-pick, check if the new
commit is empty and if so back it out if the original commit _wasn't_
empty.
This two step process is necessary because git doesn't have any options
to simply skip cherry-pick commits that have already been applied to the
tree.
Removing commits that have already been applied is particularly
important in a "deploy" pipeline triggered by a Gerrit "change-merged"
event, since the scheduler will try to cherry-pick the change on top of
the commit that just merged. Without this option, the cherry-pick will
fail and the deploy pipeline will fail with a MERGE_CONFICT.
Change-Id: I326ba49e2268197662d11fd79e46f3c020675f21
When using the rebase merge-mode a failed "merge" will leave the repo in
a state that Zuul so far could not recover from. The rebase will create
a `.git/rebase-merge` directory which is not removed when the rebase
fails.
To fix this we will abort the rebase when it fails and also remove any
existing `.git/rebase-merge` and `.git/rebase-apply` directories when
resetting the repository.
DEBUG zuul.Merger: [e: ...] Unable to merge {'branch': 'master', 'buildset_uuid': 'f7be4215f37049b4ba0236892a5d8197', 'connection': 'github', 'merge_mode': 5, 'newrev': None, 'number': 71, 'oldrev': None, 'patchset': 'e81d0b248565db290b30d9a638095947b699c76d', 'project': 'org/project', 'ref': 'refs/pull/71/head'}
Traceback (most recent call last):
File "/opt/zuul/lib/python3.10/site-packages/zuul/merger/merger.py", line 1099, in _mergeChange
commit = repo.rebaseMerge(
File "/opt/zuul/lib/python3.10/site-packages/zuul/merger/merger.py", line 626, in rebaseMerge
repo.git.rebase(*args)
File "/opt/zuul/lib/python3.10/site-packages/git/cmd.py", line 542, in <lambda>
return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
File "/opt/zuul/lib/python3.10/site-packages/git/cmd.py", line 1005, in _call_process
return self.execute(call, **exec_kwargs)
File "/opt/zuul/lib/python3.10/site-packages/git/cmd.py", line 822, in execute
raise GitCommandError(command, status, stderr_value, stdout_value)
git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)
cmdline: git rebase 39fead1852ef01a716a1c6470cee9e4197ff5587
stderr: 'fatal: It seems that there is already a rebase-merge directory, and
I wonder if you are in the middle of another rebase. If that is the
case, please try
git rebase (--continue | --abort | --skip)
If that is not the case, please
rm -fr ".git/rebase-merge"
and run me again. I am stopping in case you still have something
valuable there.
Change-Id: I8518cc5e4b3f7bbfc2c2283a2b946dee504991dd
I8e1b5b26f03cb75727d2b2e3c9310214a3eac447 introduced a regression that
prevented us from re-cloning a repo that no longer exists on the file
system (e.g. deleted by an operator) but where we still have the cached
`Repo` object.
The problem was that we only updated the remote URL of the repo object
after we wrote it to the Git config. Unfortunately, if the repo no
longer existed on the file system we would attempt to re-clone it with a
possibly outdated remote URL.
`test_set_remote_url` is a regression test for the issue described
above.
`test_set_remote_url_invalid` verifies that the original issue is fixes,
where we updated the remote URL attribute of the repo object, but fail
to update the Git config.
Change-Id: I311842ccc7af38664c28177450ea9e80e1371638
When the git command crashes or is aborted due to a timeout we might end
up with a leaked index.lock file in the affected repository.
This has the effect that all subsequent git operations that try to
create the lock will fail. Since Zuul maintains a separate lock for
serializing operations on a repositotry, we can be sure that the lock
file was leaked in a previous operation and can be removed safely.
Unable to checkout 8a87ff7cc0d0c73ac14217b653f9773a7cfce3a7
Traceback (most recent call last):
File "/opt/zuul/lib/python3.10/site-packages/zuul/merger/merger.py", line 1045, in _mergeChange
repo.checkout(ref, zuul_event_id=zuul_event_id)
File "/opt/zuul/lib/python3.10/site-packages/zuul/merger/merger.py", line 561, in checkout
repo.head.reset(working_tree=True)
File "/opt/zuul/lib/python3.10/site-packages/git/refs/head.py", line 82, in reset
self.repo.git.reset(mode, commit, '--', paths, **kwargs)
File "/opt/zuul/lib/python3.10/site-packages/git/cmd.py", line 542, in <lambda>
return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
File "/opt/zuul/lib/python3.10/site-packages/git/cmd.py", line 1005, in _call_process
return self.execute(call, **exec_kwargs)
File "/opt/zuul/lib/python3.10/site-packages/git/cmd.py", line 822, in execute
raise GitCommandError(command, status, stderr_value, stdout_value)
git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)
cmdline: git reset --hard HEAD --
stderr: 'fatal: Unable to create '/var/lib/zuul/merger-git/github/foo/foo%2Fbar/.git/index.lock': File exists.
Another git process seems to be running in this repository, e.g.
an editor opened by 'git commit'. Please make sure all processes
are terminated then try again. If it still fails, a git process
may have crashed in this repository earlier:
remove the file manually to continue.'
Change-Id: I97334383df476809c39e0d03b1af50cb59ee0cc7
GitHub supports a "rebase" merge mode where it will rebase the PR
onto the target branch and fast-forward the target branch to the
result of the rebase.
Add support for this process to the merger so that it can prepare
an effective simulated repo, and map the merge-mode to the merge
operation in the reporter so that gating behavior matches.
This change also makes a few tweaks to the merger to improve
consistency (including renaming a variable ref->base), and corrects
some typos in the similar squash merge test methods.
Change-Id: I9db1d163bafda38204360648bb6781800d2a09b4
To avoid issues with outdated Github access tokens in the Git config we
only update the remote URL on the repo object after the config update
was successful.
This also adds a missing repo lock when building the repo state.
Change-Id: I8e1b5b26f03cb75727d2b2e3c9310214a3eac447
Merges cannot be cherry-picked in git, so if a change is a merge, do a
`git merge` instead of a cherry-pick to match how Gerrit will merge the
change.
Change-Id: I9bc7025d2371913b63f0a6723aff480e7e63d8a3
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
The fix including 2 parts:
1. For Gtihub, we use the base_sha instead of target branch to
be passed as "tosha" parameter to get precise changed files
2. In method getFilesChanges(), use diff() result to filter out
those files that changed and reverted between commits.
The reason we do not direcly use diff() is that for those
drivers other than github, the "base_sha" is not available yet,
using diff() may include unexpected files when target branch
has diverged from the feature branch.
This solution works for 99.9% of the caseses, it may still get
incorrect list of changed files in following corner case:
1. In non-github connection, whose base_sha is not implented, and
2. Files changed and reverted between commits in the change, and
3. The same file has also diverged in target branch.
The above corner case can be fixed by making base_sha available in
other drivers.
Change-Id: Ifae7018a8078c16f2caf759ae675648d8b33c538
If a merger or executor is unable to reset a repo, we currently
simply log the message "Unable to reset repo". Instead, let's
assume that it is permanently broken and rmtree it so that future
attempts will automatically recover.
Change-Id: I17b051d70a9c5800019bf9ef7e0800558614cadd
Some merge operations catch too generic exceptions which causes
BrokeProcessPool exceptions to never reach the executor to allow the
executor to recover.
Bubble these exceptions up to the exececutor for them to be handled.
Change-Id: I77d4d381e12195bcfe7d831a2b9e6d361b90f5a2
It can happen that the remote ref (corresponding to the branch in
cache) is not available when local workspace is cloned.
Fix this issue by creating the remote ref when it does not exist.
Change-Id: I68244e0b5aa3c8b6e15693ffc2897d4f416e0d5c
This change adds support for configuring non-top-level directories
(e.g. `foobar/zuul.d/`) as an extra config path which did not work so
far.
It's not clear if this was a bug or intended behavior that was just not
documented.
Change-Id: I1bc468130c9324a2e1b5d7f50b42fdc045eaa741
This is an attempt to avoid getting the refs twice on the repo and
simplify _saveRepoState by directly using getPackedRefs.
Change-Id: I27876571451554caca19bdf9ae7ff502d2d4e062
When the initial merge job for a queue item fails, users typically
see a message saying "this project or one of dependencies failed
to merge". To help users and/or administrators more quickly identify
the problem, include connection project and change information in
a warning message posted to the code review system.
Change-Id: If1bced80b87b908f63867083efb306ebe02ed1ee
The reverted change can lead to the listing of files that are not
changed in the referenced commit(s). This can e.g. happen if the base
branch (e.g. master) has diverged from the feature branch.
This is now also tested to avoid regressions in the future. The issue
related to files that are added/removed in the same range of commits
(e.g. a PR) needs to be addressed in a separate change.
This reverts commit e63d7b0cdb.
Change-Id: I07bc4a09bf162fdbc4c2daeecb19e12d81241801
In case of large repository with more than 10k refs,
this method use actualy an async call from Gitpython to retrieve sha1.
Gitpython open file filesystem for each refs
For example with repository with 18k tags,
a merger instance take 100% of one CPU (not threadless) for ~ 3min
to perform the loop
To improve this, we store all sha1 of tag directly from
a git command (for_each_ref), this method open once the packedref
of repository to extract all refs.
If a ref is not in the dict we use fallback method `ref.object`
Change-Id: I8b52b39cb79527791a34ac98a25e7ee41c8d4956
This adds a variable which may be useful for debugging or auditing
the repo state of playbooks or roles for a job.
Change-Id: I86429a06ed8625faa72db6a19630de633f1694b6
The original implementation takes into account the changed fils from
all commits of a PR.
It causes a bug when files get changed and reverted in those commits.
e.g. A file is added in first commit then removed in second commit,
this file should should not be considered as a changed file in the PR.
Change-Id: I7db8b9d3f3267073c5e1a71f52e75939ffa91773
The scheduler depends on merge completed events in order to advance
the lifecycle of a queue item. Without them, items can be stuck in
the queue indefinitely.
In the case of certain merge errors, we may not have submitted a
result to the event queue. This change corrects that.
Change-Id: I9527c79868ede31f1fa68faf93ff113ac786462b
We aren't generally using type annotations, and mypy itself is
somewhat flawed, occasionally producing false positives and rarely
catching errors. Stop running it.
Change-Id: I6f24457f7d99ca11ec9228e505e6edec558baf9e
This puts the merger result events (MergeCompleted, FilesChanged) into
ZooKeeper.
This is the first step to put the merge jobs into ZooKeeper, similar to
the builds.
This doesn't change the logic how the result events are processed. The
main change is done in the scheduler callbacks (onMergeCompleted,
onFilesChanged) which now put a serializable merge result event into the
ZooKeeper result event queue rather than the local queue. The event
handler methods are adapted to work with those new events.
As the buildset is not serializable in its current state, we provide the
buildset UUID to the events and look up the corresponding buildset in
the event processing methods based on the provided pipeline and queue.
Change-Id: I033cf27bc8035afbd743e37292da37fde6d0e0b8
With some of the newer changes (most probably the global repo state),
these log messages could increase the amount of log messages in a Zuul
deployment quite heavily.
Thus move them into its own sub logger so it can be stripped or split
out via log config if needed without sacrificing other usefull logs
from zuul.Repo.
Change-Id: I6206a5938e788733950451292403d2b2525753ed
This adds the concept of a 'scheme' to the merger. Up to this point,
the merger has used the 'golang' scheme in all cases. However it is
possible with Gerrit to create a set of git repositories which collide
with each other using that scheme:
root/example.com/component
root/example.com/component/subcomponent
The users which brought this to our attention intend to use their repos
in a flat layout, like:
root/component
root/subcomponent
To resolve this we need to do two things: avoid collisions in all cases
in the internal git repo caches of the mergers and executors, and give
users options to resolve collisions in workspace checkouts.
In this change, mergers are updated to support three schemes:
* golang (the current behavior)
* flat (new behavior described above)
* unique
The unique scheme is not intended to be user-visible. It produces a
truly unique and non-conflicting name by using urllib.quote_plus. It
sacrifices legibility in order to obtain uniqueness.
The mergers and executors are updated to use the unique scheme in their
internal repo caches.
A new job attribute, 'workspace-scheme' is added to allow the user to
select between 'golang' and 'flat' when Zuul prepares the repos for
checkout.
There is one more kind of repo that Zuul prepares: the playbook repo.
Each project that supplies a playbook to a job gets a copy of its repo
checked out into a dedicated directory (with no sibling repos). In that
case there is no risk of collision, and so we retain the current behavior
of using the golang scheme for these checkouts. This allows the playbook
paths to continue to be self-explanatory. For example:
trusted/project_0/example.com/org/project/playbooks/run.yaml
Documentation and a release note are added as well.
Change-Id: I3fa1fd3c04626bfb7159aefce0f4dcb10bbaf5d9
Several changes in an attempt to clarify exactly when updates and
resets should and do happen:
* Remove the repo_state argument from Merger.getRepo()
It was unclear under what circumstances the low-level repo object
honored repo_state (not much). Remove it entirely and rely on
high-level Merger methods to deal with repo_state.
* Have merger.setRepoState() operate on one project instead of a
list of items
Part of the reason we were passing repo_state to low-level
methods was to reset the state for required projects in the
executor. Essentially there were three cases: projects of change
items, projects of non-change items, and projects of neither but
in required-projects. The low-level repo_state usage only
handled the last, the first is easy, and the second we handled by
creating a list of non-change items and passing it to
setRepoState on the merger.
A simpler method of handling all of that is to reduce it to two
cases: projects of change items (which need to be merged) and the
rest (which need to be restored). If we do that, we can maintain
a set of projects we've seen while merging in the first case,
then iterate over all the remaining projects and call
setRepoState on each in the second.
* Remove the update call from Repo.reset()
This lets us call Repo.reset() frequently (i.e., at the start of
any operation that writes to the merger's git repo working dir)
without performing a git fetch. We need to make sure we call
Repo.update() where necessary.
* Remove the reset call from Merger.updateRepo()
This will now only call repo.update(), and even that will only
happen if the repo_state says we should. So we can safely call
this before any significant operations and know that it will
update the repo if necessary.
* Add an update() call to getRepoState()
Because we removed the update() call from Repo.reset(), we need
to add one here next to the existing call to reset().
* Add a reset call to getFiles()
It relied on the reset in updateRepo.
* Set execution_context to False on the executor's main merger
The execution_context parameter determines whether we manipulate the
origin remotes to point at the previous commit. This should be set
for mergers that operate on the build work dir, but it should not
be set for the main merger within the executor (so the main merger
behaves just like a standalone merger). It previous was erroneously
set for the executor's main merger and this change corrects that.
* Add Merger.updateRepo() calls in the merger server merge method
The merger needs to update and reset each repo before merging changes.
Currently _mergeItem resets the repo the first time it encounters it.
But we still need to update the repo. We don't want to update within
the merger method because the executor performs batch updates in
parallel before starting a merge and we don't want to re-do that work.
So instead we add it to the merger server invocation, so it's only
used in the merger:merge gearman function code path.
Change-Id: I740e958357dc7bf0a6506474c5991da12ab6264e
If we pass a repo state to checkoutBranch, we should check out the
repo/branch as specified by the repo state.
FYI, there are two theoretical ways we could call checkoutBranch:
1) Without a repo state (in which case we would expect to checkout
the current value of the branch in the repo; presumable this would
be done after an update() call also without a repo state, which means
the current branch would match upstream).
2) With a repo state, in which case we would expect to check out
the branch as specified by the repo state.
Currently Zuul only uses option 2.
Change-Id: Icad68a337b3ff5fc80af32ee0a4845cc83daa14b
This is two changes squashed. First:
Fix missing repo state restore
The global repo state handling misses the restoration of the repo
states of projects that are not part of the dependency chain. This can
be generically fixed by ensuring that the repo state is restored
immediately after clone into the job workspace.
Original Change-Id: I61db67edb3952cdba7709b5b597dac93be4b6dde
Second:
Keep jobgraphs frozen across reconfiguration
This removes test cases which are no longer be relevant.
Many of these were testing various mutations across reconfigurations,
but with job graphs frozen, about the only thing that we expect to
change now is when a pipeline, project, or tenant is deleted. Test
cases are modified or added to test these.
It appears even the current code may have some bugs related to deleting
pipelines and tenants. The improved testing in this change highlighted
that. The scheduler is updated to ensure that it cancels all jobs on
pipelines or tenants that are removed from a running configuration. This
should ensure we don't leak nodes or semaphores.
Change-Id: I2e4bd2fb9222b49cb10661d28d4c52a3c994ba62
Co-Authored-By: James E. Blair <jim@acmegating.com>
This reverts commit 02ca9aeb8f.
This makes a couple of changes to make sure we're passing in the
full repo_state to updateRepo rather than the project repo state.
Change-Id: Ifca2cd48f24b9cf8eec718034c879ffe75fb6ecc
The isUpdateNeeded call was not operating on the actual dictionary
format that is passed in. The tests did not catch this because they
pass in the format that is expected. Update both the tests and the
calling code in the merger to fix.
This breaks the just-added fast-forward test, which shows us that
the current behavior really is broken.
Change-Id: I34b7dbe1d4f7032d217bca30ca9a8d3c986c1915
We discovered a regression in the global repo state that can lead to
wrong commits checked out on required projects. Further a fix for this
needs a slight re-design of the reconfiguration process. In order to
have some more time to do this revert it for now.
This reverts commit 175990ec42.
Change-Id: Ibcf3758ab886a01468095a8c588cf78db209529e