]> git.ipfire.org Git - pbs.git/commitdiff
builds: Use groups to group test builds together
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 3 May 2023 10:42:04 +0000 (10:42 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 3 May 2023 10:42:04 +0000 (10:42 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/builds.py
src/database.sql
src/templates/builds/show.html

index f6121c165c7d3bedcfa844361921c8bac5c8f058..f56e7e0754eb8791a4da90e54b9042b3c4f9028b 100644 (file)
@@ -199,7 +199,7 @@ class Builds(base.Object):
 
                return list(builds)
 
-       async def create(self, repo, package, owner=None, group=None, test_for_build=None):
+       async def create(self, repo, package, owner=None, group=None, test=False):
                """
                        Creates a new build based on the given distribution and package
                """
@@ -215,7 +215,7 @@ class Builds(base.Object):
                                pkg_id,
                                owner_id,
                                build_group_id,
-                               test_for_build_id
+                               test
                        )
                        VALUES
                        (
@@ -226,7 +226,7 @@ class Builds(base.Object):
                        package,
                        owner,
                        group,
-                       test_for_build,
+                       test,
                )
 
                # Populate cache
@@ -903,15 +903,24 @@ class Build(base.DataObject):
        # Tests Builds
 
        def is_test(self):
-               if self.data.test_for_build_id:
+               if self.data.test:
                        return True
 
                return False
 
        @lazy_property
-       def test_for_build(self):
-               if self.data.test_for_build_id:
-                       return self.backend.builds.get_by_id(self.data.test_for_build_id)
+       def test_build_for(self):
+               return self.backend.builds._get_build("""
+                       SELECT
+                               builds.*
+                       FROM
+                               build_test_builds test_builds
+                       JOIN
+                               builds ON test_builds.build_id = builds.id
+                       WHERE
+                               test_builds.test_build_id = %s
+                       """, self.id,
+               )
 
        async def create_test_builds(self):
                """
@@ -927,7 +936,7 @@ class Build(base.DataObject):
                                builds[build.pkg.name] = [build]
 
                # Create a build group for all tests
-               group = self.backend.builds.groups.create()
+               group = self.backend.builds.groups.create(owner=build.owner)
 
                # Create a test build only for the latest version of each package
                for name in builds:
@@ -940,29 +949,27 @@ class Build(base.DataObject):
                                package=build.pkg,
                                owner=self.owner,
                                group=group,
-                               test_for_build=self,
+                               test=True,
                        )
-                       self.test_builds.append(t)
+                       group.builds.append(t)
+
+               # Cache the group
+               self.test_builds = group
 
+               # Return the group
                return self.test_builds
 
-       @lazy_property
-       def test_builds(self):
+       def get_test_builds(self):
                """
                        Returns all test builds
                """
-               builds = self.backend.builds._get_builds("""
-                       SELECT
-                               *
-                       FROM
-                               builds
-                       WHERE
-                               deleted_at IS NULL
-                       AND
-                               test_for_build_id = %s
-               """, self.id)
+               if self.data.test_group_id:
+                       return self.backend.builds.groups.get_by_id(self.data.test_group_id)
 
-               return list(builds)
+       def set_test_builds(self, group):
+               self._set_attribute("test_group_id", group)
+
+       test_builds = lazy_property(get_test_builds, set_test_builds)
 
 
 class Groups(base.Object):
@@ -992,23 +999,31 @@ class Groups(base.Object):
                        """, id,
                )
 
-       def create(self):
+       def create(self, owner=None):
                """
                        Creates a new Build Group
                """
                return self._get_group("""
                        INSERT INTO
                                build_groups
-                       DEFAULT VALUES
+                       (
+                               created_by
+                       )
+                       VALUES(
+                               %s
+                       )
                        RETURNING
                                *
-                       """,
+                       """, owner,
                )
 
 
 class Group(base.DataObject):
        table = "build_groups"
 
+       def __iter__(self):
+               return iter(self.builds)
+
        # UUID
 
        @property
@@ -1031,7 +1046,7 @@ class Group(base.DataObject):
                        FROM
                                builds
                        WHERE
-                               deleted_at IS FALSE
+                               deleted_at IS NULL
                        AND
                                build_group_id = %s
                        """, self.id,
index f2c1b6dc43e779fcf52cfc35832903fa5ea4c6a6..ec5416b6c00f151cf4db75ceab2b05f7f6e6909b 100644 (file)
@@ -63,7 +63,10 @@ CREATE TABLE public.build_comments (
 CREATE TABLE public.build_groups (
     id integer NOT NULL,
     uuid uuid DEFAULT gen_random_uuid() NOT NULL,
-    created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
+    created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+    created_by integer,
+    deleted_at timestamp without time zone,
+    deleted_by integer
 );
 
 
@@ -99,6 +102,47 @@ CREATE TABLE public.build_packages (
 );
 
 
+--
+-- Name: builds; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE public.builds (
+    id integer NOT NULL,
+    uuid uuid DEFAULT gen_random_uuid() NOT NULL,
+    pkg_id integer NOT NULL,
+    severity text,
+    message text,
+    created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+    build_repo_id integer NOT NULL,
+    owner_id integer,
+    priority integer DEFAULT 0 NOT NULL,
+    bug_ids integer[] DEFAULT ARRAY[]::integer[] NOT NULL,
+    finished_at timestamp without time zone,
+    failed boolean DEFAULT false NOT NULL,
+    deleted_at timestamp without time zone,
+    deleted_by integer,
+    build_group_id integer,
+    deprecating_build_id integer,
+    deprecated_at timestamp without time zone,
+    deprecated_by integer,
+    test_group_id integer,
+    test boolean DEFAULT false NOT NULL
+);
+
+
+--
+-- Name: build_test_builds; Type: VIEW; Schema: public; Owner: -
+--
+
+CREATE VIEW public.build_test_builds AS
+ SELECT builds.id AS build_id,
+    test_builds.id AS test_build_id
+   FROM ((public.builds
+     JOIN public.build_groups ON ((builds.test_group_id = build_groups.id)))
+     JOIN public.builds test_builds ON ((test_builds.build_group_id = build_groups.id)))
+  WHERE ((builds.deleted_at IS NULL) AND (build_groups.deleted_at IS NULL));
+
+
 --
 -- Name: build_watchers; Type: TABLE; Schema: public; Owner: -
 --
@@ -193,33 +237,6 @@ CREATE SEQUENCE public.builders_id_seq
 ALTER SEQUENCE public.builders_id_seq OWNED BY public.builders.id;
 
 
---
--- Name: builds; Type: TABLE; Schema: public; Owner: -
---
-
-CREATE TABLE public.builds (
-    id integer NOT NULL,
-    uuid uuid DEFAULT gen_random_uuid() NOT NULL,
-    pkg_id integer NOT NULL,
-    severity text,
-    message text,
-    created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
-    build_repo_id integer NOT NULL,
-    owner_id integer,
-    priority integer DEFAULT 0 NOT NULL,
-    bug_ids integer[] DEFAULT ARRAY[]::integer[] NOT NULL,
-    finished_at timestamp without time zone,
-    failed boolean DEFAULT false NOT NULL,
-    deleted_at timestamp without time zone,
-    deleted_by integer,
-    build_group_id integer,
-    deprecating_build_id integer,
-    deprecated_at timestamp without time zone,
-    deprecated_by integer,
-    test_for_build_id integer
-);
-
-
 --
 -- Name: builds_bugs_updates; Type: TABLE; Schema: public; Owner: -
 --
@@ -396,7 +413,7 @@ CREATE TABLE public.jobs (
 
 CREATE VIEW public.job_queue AS
  SELECT jobs.id AS job_id,
-    rank() OVER (ORDER BY (NOT (builds.test_for_build_id IS NULL)), builds.priority DESC, jobs.created_at) AS rank,
+    rank() OVER (ORDER BY (NOT builds.test), builds.priority DESC, jobs.created_at) AS rank,
     jobs.arch
    FROM (public.jobs
      LEFT JOIN public.builds ON ((jobs.build_id = builds.id)))
@@ -688,7 +705,7 @@ CREATE VIEW public.package_estimated_build_times AS
    FROM ((public.jobs
      LEFT JOIN public.builds ON ((jobs.build_id = builds.id)))
      LEFT JOIN public.packages ON ((builds.pkg_id = packages.id)))
-  WHERE ((jobs.deleted_at IS NULL) AND (jobs.started_at IS NOT NULL) AND (jobs.finished_at IS NOT NULL) AND (jobs.failed IS FALSE) AND (builds.test_for_build_id IS NULL))
+  WHERE ((jobs.deleted_at IS NULL) AND (jobs.started_at IS NOT NULL) AND (jobs.finished_at IS NOT NULL) AND (jobs.failed IS FALSE) AND (builds.test IS FALSE))
   GROUP BY packages.name, jobs.arch;
 
 
@@ -1467,7 +1484,7 @@ CREATE INDEX build_comments_user_id ON public.build_comments USING btree (user_i
 -- Name: build_groups_uuid; Type: INDEX; Schema: public; Owner: -
 --
 
-CREATE UNIQUE INDEX build_groups_uuid ON public.build_groups USING btree (uuid);
+CREATE UNIQUE INDEX build_groups_uuid ON public.build_groups USING btree (uuid) WHERE (deleted_at IS NULL);
 
 
 --
@@ -1526,13 +1543,6 @@ CREATE INDEX builds_deprecating_build_id ON public.builds USING btree (deprecati
 CREATE INDEX builds_pkg_id ON public.builds USING btree (pkg_id) WHERE (deleted_at IS NULL);
 
 
---
--- Name: builds_test_for_build_id; Type: INDEX; Schema: public; Owner: -
---
-
-CREATE INDEX builds_test_for_build_id ON public.builds USING btree (test_for_build_id) WHERE (deleted_at IS NULL);
-
-
 --
 -- Name: builds_uuid; Type: INDEX; Schema: public; Owner: -
 --
@@ -1754,6 +1764,22 @@ CREATE UNIQUE INDEX uploads_uuid ON public.uploads USING btree (uuid);
 CREATE TRIGGER on_update_current_timestamp BEFORE UPDATE ON public.sources FOR EACH ROW EXECUTE FUNCTION public.on_update_current_timestamp_sources();
 
 
+--
+-- Name: build_groups build_groups_created_by; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.build_groups
+    ADD CONSTRAINT build_groups_created_by FOREIGN KEY (created_by) REFERENCES public.users(id);
+
+
+--
+-- Name: build_groups build_groups_deleted_by; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.build_groups
+    ADD CONSTRAINT build_groups_deleted_by FOREIGN KEY (deleted_by) REFERENCES public.users(id);
+
+
 --
 -- Name: build_packages build_packages_build_id; Type: FK CONSTRAINT; Schema: public; Owner: -
 --
@@ -1875,11 +1901,11 @@ ALTER TABLE ONLY public.builds
 
 
 --
--- Name: builds builds_test_for_build_id; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: builds builds_test_group_id; Type: FK CONSTRAINT; Schema: public; Owner: -
 --
 
 ALTER TABLE ONLY public.builds
-    ADD CONSTRAINT builds_test_for_build_id FOREIGN KEY (test_for_build_id) REFERENCES public.builds(id);
+    ADD CONSTRAINT builds_test_group_id FOREIGN KEY (test_group_id) REFERENCES public.build_groups(id);
 
 
 --
index e54075bbaf37383f2b6a21ae310228d7fe921e9c..8e68561069052dcdac8a66d0c541ac36cd0cf23b 100644 (file)
        <section class="section">
                <h1 class="title is-1">{{ build }}</h1>
 
-               {% if build.pkg.summary %}
+               {% if build.is_test() %}
                        <h6 class="subtitle is-6">
-                               {{ build.pkg.summary }}
+                               <span class="tag is-warning">{{ _("Test Build") }}</span>
+
+                               <a href="/builds/{{ build.test_build_for.uuid }}">
+                                       {{ build.test_build_for }}
+                               </a>
                        </h6>
+               {% else %}
+                       {% if build.pkg.summary %}
+                               <h6 class="subtitle is-6">
+                                       {{ build.pkg.summary }}
+                               </h6>
+                       {% end %}
                {% end %}
 
                <div class="columns">