diff --git a/build/migrations/0005_buildrelease_triggered_jobs.py b/build/migrations/0005_buildrelease_triggered_jobs.py new file mode 100644 index 0000000..228d771 --- /dev/null +++ b/build/migrations/0005_buildrelease_triggered_jobs.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2022-06-08 08:29 +from django.db import migrations +from django.db import models + + +class Migration(migrations.Migration): + + dependencies = [ + ("build", "0004_start_date"), + ] + + operations = [ + migrations.AddField( + model_name="buildrelease", + name="triggered_jobs", + field=models.TextField(editable=False, null=True), + ), + ] diff --git a/build/models.py b/build/models.py index 32e454e..b2b639a 100644 --- a/build/models.py +++ b/build/models.py @@ -150,6 +150,7 @@ class BuildRelease(models.Model): triggered_projects = models.TextField(null=True, editable=False) failed_projects = models.TextField(null=True, editable=False) pool_size = models.SmallIntegerField(default=0, editable=False) + triggered_jobs = models.TextField(null=True, editable=False) objects = BuildReleaseManager() def __str__(self): @@ -213,6 +214,22 @@ class BuildRelease(models.Model): return [x.strip() for x in self.triggered_projects.split(",")] return [] + @property + def triggered_jobs_list(self): + if self.triggered_jobs is not None: + return [x.strip() for x in self.triggered_jobs.split(",")] + return [] + + def append_triggered_job(self, value): + if value in self.triggered_jobs_list: + return False + if self.triggered_jobs is None: + self.triggered_jobs = value + else: + self.triggered_jobs += ",{}".format(value) + self.save() + return True + def append_triggered(self, value): if value in self.triggered_projects_list: return False diff --git a/build/tasks.py b/build/tasks.py index 845d363..869830d 100644 --- a/build/tasks.py +++ b/build/tasks.py @@ -95,6 +95,9 @@ def build_resume(pk): else: log.debug("BuildRelease has no next") if br.release == "release-trunk-weekly": - url = trigger_build_matrix() - log.info("build_matrix triggered", instance=str(br), url=url) + url = trigger_build_matrix(br) + if url is not None: + log.info( + "build_matrix triggered", instance=str(br), url=url + ) break diff --git a/build/test/test_models.py b/build/test/test_models.py index cfe31b0..512f509 100644 --- a/build/test/test_models.py +++ b/build/test/test_models.py @@ -408,6 +408,32 @@ class BuildReleaseStepsTest(BaseTest): ) self.assertIsNone(self.br.next) + def test_append_triggered_jobs(self): + self.assertIsNone(self.br.triggered_jobs) + res = self.br.append_triggered_job("fake-external-job") + self.assertTrue(res) + self.assertEqual(self.br.triggered_jobs, "fake-external-job") + self.assertEqual( + self.br.triggered_jobs_list, + [ + "fake-external-job", + ], + ) + + res = self.br.append_triggered_job("fake-external-job") + self.assertFalse(res) + self.assertEqual(self.br.triggered_jobs, "fake-external-job") + + res = self.br.append_triggered_job("other-external-job") + self.assertTrue(res) + self.assertEqual( + self.br.triggered_jobs, "fake-external-job,other-external-job" + ) + self.assertEqual( + self.br.triggered_jobs_list, + ["fake-external-job", "other-external-job"], + ) + @override_settings(JBI_ALLOWED_HOSTS=["fake.local"]) @patch("repoapi.utils.dlfile") diff --git a/build/test/test_tasks.py b/build/test/test_tasks.py index 45b9173..f5f2d96 100644 --- a/build/test/test_tasks.py +++ b/build/test/test_tasks.py @@ -292,4 +292,4 @@ class WeeklyTest(BaseTest): self.assertTrue(br.built_projects.endswith("ngcp-prompts")) self.assertEqual(br.pool_size, 0) tb.assert_not_called() - tbm.assert_called_once_with() + tbm.assert_called_once_with(br) diff --git a/build/test/test_utils.py b/build/test/test_utils.py index 64f96d4..73ac508 100644 --- a/build/test/test_utils.py +++ b/build/test/test_utils.py @@ -15,6 +15,7 @@ import re from unittest.mock import patch +from django.apps import apps from django.test import override_settings from django.test import SimpleTestCase @@ -25,7 +26,9 @@ from build.utils import get_simple_release from build.utils import is_release_trunk from build.utils import ReleaseConfig from build.utils import trigger_build +from build.utils import trigger_build_matrix from build.utils import trigger_copy_deps +from repoapi.test.base import BaseTest class SimpleIsReleaseTrunkTest(SimpleTestCase): @@ -337,3 +340,44 @@ class TriggerBuild(SimpleTestCase): params["token"] = settings.JENKINS_TOKEN self.assertEqual(res, "{base}/job/{project}/".format(**params)) openurl.assert_called_once_with(url.format(**params)) + + +@patch("build.utils.open_jenkins_url") +@override_settings(DEBUG=False) +class TriggerBuildMatrix(BaseTest): + fixtures = [ + "test_weekly", + ] + release = "release-trunk-weekly" + release_uuid = "dbe569f7-eab6-4532-a6d1-d31fb559649b" + + def test_trigger_build_matrix(self, openurl): + BuildRelease = apps.get_model("build", "BuildRelease") + br = BuildRelease.objects.get(uuid=self.release_uuid) + params = { + "base": settings.JENKINS_URL, + "token": settings.JENKINS_TOKEN, + "job": "weekly-build-matrix-trunk-weekly", + "cause": "repoapi finished to build trunk-weekly", + } + url = ( + "{base}/job/{job}/buildWithParameters?token={token}&cause={cause}" + ) + res = trigger_build_matrix(br) + self.assertEqual(res, "{base}/job/{job}/".format(**params)) + openurl.assert_called_once_with(url.format(**params)) + + def test_trigger_build_matrix_ko(self, openurl): + BuildRelease = apps.get_model("build", "BuildRelease") + br = BuildRelease.objects.get(uuid=self.release_uuid) + params = { + "base": settings.JENKINS_URL, + "token": settings.JENKINS_TOKEN, + "job": "weekly-build-matrix-trunk-weekly", + "cause": "repoapi finished to build trunk-weekly", + } + res = br.append_triggered_job(params["job"]) + self.assertTrue(res) + res = trigger_build_matrix(br) + self.assertIsNone(res) + openurl.assert_not_called() diff --git a/build/utils.py b/build/utils.py index 834ccc0..79f640c 100644 --- a/build/utils.py +++ b/build/utils.py @@ -71,7 +71,7 @@ def get_common_release(version): return "master" -def trigger_build_matrix(): +def trigger_build_matrix(br): params = { "base": settings.JENKINS_URL, "token": urllib.parse.quote(settings.JENKINS_TOKEN), @@ -79,6 +79,9 @@ def trigger_build_matrix(): "cause": "repoapi finished to build trunk-weekly", } url = _url.format(**params) + if not br.append_triggered_job(params["job"]): + logger.info("{} already triggered, skip".format(params["job"])) + return if settings.DEBUG: logger.info("Debug mode, would trigger: %s", url) else: