diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e547ac494f4f1b2144edad11c557560ba38f63d6..af5647a9abf92d1e26719665d4935b4a9c4b1979 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,6 +35,13 @@ variables: For instance use `*` to process all updates, `dash` to only process `pkg/dash`. Leave it empty to not trigger any update. value: "" + TRIGGER_SECURITY_UPDATES: + description: | + Set to `1` to pull only security updates from upstream. + value: "" + options: + - "" + - "1" TRIGGER_GITLAB_RULEZ: description: | Set to `apply` to run gitlab-rulez on GitLab repositories. @@ -623,6 +630,7 @@ trigger-updates: --gitlab-server-url "${CI_SERVER_URL}" --projects packaging.json --filter "${TRIGGER_UPDATES}" + ${TRIGGER_SECURITY_UPDATES:+--only-security} ${DEBUG:+--debug} ${LOG_TO_FILE:+--log-to-file $LOG_TO_FILE} artifacts: diff --git a/bin/dashboard b/bin/dashboard index 4251769b6835ddd3ef58729a7aca94ec93995514..84a7a889bcdf0a58f8a44f923ddf6a293a6298ce 100755 --- a/bin/dashboard +++ b/bin/dashboard @@ -74,6 +74,12 @@ def preprocess_packaging_data(data): "total_packaging_delta": sum( count_reports(p, lambda r: r["domain"] == "delta") for p in packages ), + "wrong_settings_count": sum( + count_reports( + p, lambda r: r["domain"] == "git" and r["kind"] == "wrong-settings" + ) + for p in packages + ), } data["summary"] = summary diff --git a/bin/trigger-updates b/bin/trigger-updates index f2c4398f47e1daf4397c818e9b8390fe7338d15d..168af346612087913d3c80264043ff78f609a307 100755 --- a/bin/trigger-updates +++ b/bin/trigger-updates @@ -23,39 +23,53 @@ def connect(gitlab_instance, gitlab_server_url, gitlab_api_token): def trigger_updates(gl, data, filterglob): all_packages = data["packages"] - all_count = sum( - len(package.get("updates", [])) for package in all_packages.values() - ) - filtered_packages = [ - p - for package_name, p in all_packages.items() - if fnmatch.fnmatch(package_name, filterglob) - ] - filtered_count = sum( - len(package.get("updates", [])) for package in filtered_packages - ) + all_packages_reports = { + package: values + for package, values in all_packages.items() + if "reports" in values + } + all_packages_updates = {} + all_count = 0 + filtered_count = 0 + for package, values in all_packages_reports.items(): + for report in values["reports"]: + if report["domain"] == "update" and report["kind"] == "available": + all_count += 1 + all_packages_updates.update({package: values}) + if fnmatch.fnmatch(package, filterglob): + filtered_count += 1 logging.info( f"Processing {filtered_count} updates matching the '{filterglob}' filter, {all_count} total" ) - for package_name, package in all_packages.items(): + for package_name, package in all_packages_updates.items(): should_trigger = fnmatch.fnmatch(package_name, filterglob) - for update in package.get("updates", []): - path_with_namespace = package["git"]["path_with_namespace"] - ref = update.get("base", update["branch"])["name"] - print( - f"{path_with_namespace}:", - "Trigger" if should_trigger else "Skip", - ref, - update["branch"]["version"], - "→", - update["upstream"]["version"], - ) - p = gl.projects.get(path_with_namespace, lazy=True) - update["pipeline"] = {"ref": ref} - if should_trigger: - pipeline = p.pipelines.create({"ref": ref}) - print(" ", pipeline.web_url) - update["pipeline"].update(id=pipeline.id, web_url=pipeline.web_url) + for report in package["reports"]: + if report["domain"] == "update" and report["kind"] == "available": + path_with_namespace = package["git"]["path_with_namespace"] + ref = report.get("base")["name"] + + should_trigger_security = True + if args.only_security: + if not report["branch"].endswith("-security"): + should_trigger_security = False + logging.debug( + f'Skipping {package_name} {report["upstream"]["version"]} from {report["branch"]} due to --only-security' + ) + + print( + f"{path_with_namespace}:", + "Trigger" if should_trigger and should_trigger_security else "Skip", + ref, + report["base"]["version"], + "→", + report["upstream"]["version"], + ) + p = gl.projects.get(path_with_namespace, lazy=True) + report["pipeline"] = {"ref": ref} + if should_trigger and should_trigger_security: + pipeline = p.pipelines.create({"ref": ref}) + print(" ", pipeline.web_url) + report["pipeline"].update(id=pipeline.id, web_url=pipeline.web_url) if __name__ == "__main__": @@ -91,6 +105,11 @@ if __name__ == "__main__": "--filter", help="trigger updates only on matching projects", ) + parser.add_argument( + "--only-security", + action="store_true", + help="trigger only security updates", + ) parser.add_argument( "--gitlab-instance", type=str, diff --git a/templates/base.html.jinja2 b/templates/base.html.jinja2 index 05b4f4e9fc28a74301b2e12fe8b786df0ae51cc3..b908998be8eb44c8922fd03515ac69c7a618c175 100644 --- a/templates/base.html.jinja2 +++ b/templates/base.html.jinja2 @@ -49,6 +49,10 @@ {% block summary %}{% endblock %} </div> + <div class="d-flex align-items-baseline justify-content-between"> + {% block buttons %}{% endblock %} + </div> + <div class="d-flex align-items-baseline justify-content-between"> {% block error %}{% endblock %} </div> diff --git a/templates/index.html.jinja2 b/templates/index.html.jinja2 index 0ee107c61823a7cdf539d11cc8e22bdf5d99b197..47de1ad5043340c09bf4178983337de99a271283 100644 --- a/templates/index.html.jinja2 +++ b/templates/index.html.jinja2 @@ -184,10 +184,12 @@ </div> </div> </ul> +{% endblock %} - <div> - {% if meta.new_pipeline_url -%} - <a class="btn btn-primary" +{% block buttons %} + {% if meta.new_pipeline_url -%} + <ul class="list-inline mr-auto"> + <a class="btn btn-primary {{'disabled' if not summary.wrong_settings_count }}" href="{{- meta.new_pipeline_url -}}&var[TRIGGER_GITLAB_RULEZ]=apply ">Run gitlab-rulez</a> <a class="btn btn-primary {{'disabled' if not summary.total_updates_count }}" @@ -196,8 +198,14 @@ &var[TRIGGER_FROM_JOB]={{- meta.current_job_url -}} {%- endif -%} ">Update all</a> - {%- endif %} - </div> + <a class="btn btn-danger {{'disabled' if not summary.update_errors_count }}" + href="{{- meta.new_pipeline_url -}}&var[TRIGGER_UPDATES]=*&var[TRIGGER_SECURITY_UPDATES]=1 + {%- if meta.current_job_url -%} + &var[TRIGGER_FROM_JOB]={{- meta.current_job_url -}} + {%- endif -%} + ">Update security</a> + </ul> + {%- endif %} {% endblock %} {% block error %}