checkupdates: push_commits() to push auto-branch when new commits

This commit is contained in:
Hans-Christoph Steiner 2022-06-27 17:22:03 +02:00 committed by linsui
parent a9db97d214
commit 4c225f02d2
2 changed files with 101 additions and 0 deletions

View file

@ -18,6 +18,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import git
import os import os
import re import re
import urllib.request import urllib.request
@ -683,6 +684,46 @@ def get_last_build_from_app(app: metadata.App) -> metadata.Build:
return metadata.Build() return metadata.Build()
def push_commits(remote_name='origin'):
"""Push commits using either appid or 'checkupdates' as branch name."""
git_repo = git.Repo.init('.')
files = set()
upstream_main = 'main' if 'main' in git_repo.remotes.upstream.refs else 'master'
local_main = 'main' if 'main' in git_repo.refs else 'master'
for commit in git_repo.iter_commits(f'upstream/{upstream_main}...{local_main}'):
files.update(commit.stats.files.keys())
branch_name = 'checkupdates'
files = list(files)
if len(files) == 1:
m = re.match(r'metadata/([^\s]+)\.yml', files[0])
if m:
branch_name = m.group(1) # appid
if len(files) > 0:
git_repo.create_head(branch_name, force=True)
remote = git_repo.remotes[remote_name]
pushinfos = remote.push(
branch_name, force=True, set_upstream=True, progress=progress
)
for pushinfo in pushinfos:
if pushinfo.flags & (
git.remote.PushInfo.ERROR
| git.remote.PushInfo.REJECTED
| git.remote.PushInfo.REMOTE_FAILURE
| git.remote.PushInfo.REMOTE_REJECTED
):
# Show potentially useful messages from git remote
if progress:
for line in progress.other_lines:
if line.startswith('remote:'):
logging.debug(line)
raise FDroidException(
f'{remote.url} push failed: {pushinfo.flags} {pushinfo.summary}'
)
else:
logging.debug(remote.url + ': ' + pushinfo.summary)
def status_update_json(processed: list, failed: dict) -> None: def status_update_json(processed: list, failed: dict) -> None:
"""Output a JSON file with metadata about this run.""" """Output a JSON file with metadata about this run."""
logging.debug(_('Outputting JSON')) logging.debug(_('Outputting JSON'))

View file

@ -2,9 +2,13 @@
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 # http://www.drdobbs.com/testing/unit-testing-with-python/240165163
import git
import logging import logging
import os import os
import shutil
import sys import sys
import tempfile
import time
import unittest import unittest
from unittest import mock from unittest import mock
from pathlib import Path from pathlib import Path
@ -27,6 +31,12 @@ class CheckupdatesTest(unittest.TestCase):
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
self.basedir = localmodule / 'tests' self.basedir = localmodule / 'tests'
os.chdir(self.basedir) os.chdir(self.basedir)
self.testdir = tempfile.TemporaryDirectory(
str(time.time()), self._testMethodName + '_'
)
def tearDown(self):
self.testdir.cleanup()
def test_autoupdatemode_no_suffix(self): def test_autoupdatemode_no_suffix(self):
fdroidserver.checkupdates.config = {} fdroidserver.checkupdates.config = {}
@ -317,6 +327,56 @@ class CheckupdatesTest(unittest.TestCase):
self.assertEqual(vername, '2') self.assertEqual(vername, '2')
self.assertEqual(vercode, 2) self.assertEqual(vercode, 2)
def test_push_commits(self):
testdir = self.testdir.name
os.chdir(testdir)
os.mkdir('metadata')
for f in (self.basedir / 'metadata').glob('*.yml'):
shutil.copy(f, 'metadata')
git_repo = git.Repo.init(testdir)
git_repo.git.add(all=True)
git_repo.index.commit("all metadata files")
git_remote_upstream = os.path.join(testdir, 'git_remote_upstream')
upstream = git.Repo.init(git_remote_upstream, bare=True)
git_repo.create_remote('upstream', 'file://' + git_remote_upstream)
git_remote_origin = os.path.join(testdir, 'git_remote_origin')
origin = git.Repo.init(git_remote_origin, bare=True)
git_repo.create_remote('origin', 'file://' + git_remote_origin)
for remote in git_repo.remotes:
remote.push(git_repo.active_branch)
self.assertEqual(git_repo.head, upstream.head)
self.assertEqual(origin.head, upstream.head)
# pretend that checkupdates ran but didn't create any new commits
fdroidserver.checkupdates.push_commits()
appid = 'org.adaway'
self.assertNotIn(appid, git_repo.branches)
self.assertNotIn('checkupdates', git_repo.branches)
self.assertNotIn(appid, git_repo.remotes.origin.repo.branches) # TODO fix
# now make commit
app = fdroidserver.metadata.read_metadata({appid: -1})[appid]
build = fdroidserver.metadata.Build()
build.versionName = 'fake'
build.versionCode = 999999999
app.Builds.append(build)
metadata_file = 'metadata/%s.yml' % appid
fdroidserver.metadata.write_metadata(metadata_file, app)
git_repo.index.add(metadata_file)
git_repo.index.commit('changed ' + appid)
# and push the new commit to the dynamic branch
fdroidserver.checkupdates.push_commits()
self.assertIn(appid, git_repo.branches)
self.assertIn(appid, git_repo.remotes.origin.refs)
self.assertNotIn('checkupdates', git_repo.branches)
self.assertNotIn(appid, git_repo.remotes.upstream.refs)
def test_make_merge_request(self):
testdir = self.testdir.name
os.chdir(testdir)
if __name__ == "__main__": if __name__ == "__main__":
import argparse import argparse