diff --git a/.github/workflows/_Test-OCI-Factory.yaml b/.github/workflows/_Test-OCI-Factory.yaml index 001e5a5c..a54122c8 100644 --- a/.github/workflows/_Test-OCI-Factory.yaml +++ b/.github/workflows/_Test-OCI-Factory.yaml @@ -117,7 +117,6 @@ jobs: # test-oci-compliance: true # test-vulnerabilities: true - # # Test workflow used in continuous testing # test-vulnerability-scan: # name: Test vulnerability scan workflow diff --git a/oci/identity-platform-admin-ui/_releases.json b/oci/identity-platform-admin-ui/_releases.json index aed77df3..5465781d 100644 --- a/oci/identity-platform-admin-ui/_releases.json +++ b/oci/identity-platform-admin-ui/_releases.json @@ -15,9 +15,9 @@ } }, "1-22.04": { - "end-of-life": "2025-05-12T00:00:00Z", + "end-of-life": "2025-06-12T00:00:00Z", "stable": { - "target": "4" + "target": "9" }, "candidate": { "target": "1-22.04_stable" @@ -40,5 +40,17 @@ "edge": { "target": "6" } + }, + "1.22-22.04": { + "end-of-life": "2024-12-26T00:00:00Z", + "candidate": { + "target": "10" + }, + "edge": { + "target": "10" + }, + "beta": { + "target": "1.22-22.04_candidate" + } } } \ No newline at end of file diff --git a/oci/identity-platform-login-ui/_releases.json b/oci/identity-platform-login-ui/_releases.json index e5865966..1afb4dae 100644 --- a/oci/identity-platform-login-ui/_releases.json +++ b/oci/identity-platform-login-ui/_releases.json @@ -13,5 +13,17 @@ "edge": { "target": "0-22.04_beta" } + }, + "0.18-22.04": { + "end-of-life": "2024-12-19T00:00:00Z", + "candidate": { + "target": "9" + }, + "edge": { + "target": "9" + }, + "beta": { + "target": "0.18-22.04_candidate" + } } } \ No newline at end of file diff --git a/oci/kratos/_releases.json b/oci/kratos/_releases.json index b58b306d..b00455b0 100644 --- a/oci/kratos/_releases.json +++ b/oci/kratos/_releases.json @@ -15,9 +15,9 @@ } }, "1-22.04": { - "end-of-life": "2025-02-13T00:00:00Z", + "end-of-life": "2025-03-03T00:00:00Z", "stable": { - "target": "3" + "target": "10" }, "candidate": { "target": "1-22.04_stable" diff --git a/oci/metrics-proxy/_releases.json b/oci/metrics-proxy/_releases.json new file mode 100644 index 00000000..90c686c9 --- /dev/null +++ b/oci/metrics-proxy/_releases.json @@ -0,0 +1,47 @@ +{ + "0.1.1-22.04": { + "end-of-life": "2025-11-27T00:00:00Z", + "stable": { + "target": "1" + }, + "candidate": { + "target": "0.1.1-22.04_stable" + }, + "beta": { + "target": "0.1.1-22.04_candidate" + }, + "edge": { + "target": "0.1.1-22.04_beta" + } + }, + "0.1-22.04": { + "end-of-life": "2025-11-27T00:00:00Z", + "stable": { + "target": "1" + }, + "candidate": { + "target": "0.1-22.04_stable" + }, + "beta": { + "target": "0.1-22.04_candidate" + }, + "edge": { + "target": "0.1-22.04_beta" + } + }, + "0-22.04": { + "end-of-life": "2025-11-27T00:00:00Z", + "stable": { + "target": "1" + }, + "candidate": { + "target": "0-22.04_stable" + }, + "beta": { + "target": "0-22.04_candidate" + }, + "edge": { + "target": "0-22.04_beta" + } + } +} \ No newline at end of file diff --git a/oci/metrics-proxy/contacts.yaml b/oci/metrics-proxy/contacts.yaml new file mode 100644 index 00000000..437db0b4 --- /dev/null +++ b/oci/metrics-proxy/contacts.yaml @@ -0,0 +1,5 @@ +notify: + emails: + - observability@lists.launchpad.net + mattermost-channels: + - 1ayd5kim67bbing34i3h1x9uac \ No newline at end of file diff --git a/oci/metrics-proxy/documentation.yaml b/oci/metrics-proxy/documentation.yaml new file mode 100644 index 00000000..544a09e3 --- /dev/null +++ b/oci/metrics-proxy/documentation.yaml @@ -0,0 +1,43 @@ +version: 1 +# --- OVERVIEW INFORMATION --- +application: metrics-proxy +description: > + Metrics Proxy is a lightweight proxy designed to expose a unified metrics endpoint for multiple Kubernetes pods. + The proxy watches for pods in a Kubernetes cluster and listens on a configurable port, + where it exposes aggregated metrics on a configurable endpoint. + Read more on the [project repo](https://github.com/canonical/metrics-k8s-proxy). +# --- USAGE INFORMATION --- +docker: + parameters: + - -p 15090:15090 + access: Access aggregated metrics at `http://localhost:15090`. + +parameters: + - type: -e + value: 'TZ=UTC' + description: Timezone setting for the container. + - type: -p + value: '15090:15090' + description: Port mapping for accessing the metrics-proxy aggregated metrics endpoint. + - type: -e + value: 'POD_LABEL_SELECTOR="foo=bar"' + description: Specify labels to filter Kubernetes pods for metrics aggregation. + - type: -e + value: 'PORT="15090"' + description: The port on which the metrics-proxy listens for scrape requests. + - type: -e + value: 'SCRAPE_TIMEOUT="9s"' + description: Configures the timeout duration for scraping metrics from the pods. + +debug: + text: | + ### Debugging + + To debug the container: + ```bash + docker exec -it metrics-proxy-container pebble logs -f metrics-proxy + ``` + To get an interactive shell: + ```bash + docker exec -it metrics-proxy-container /bin/bash + ``` \ No newline at end of file diff --git a/oci/metrics-proxy/image.yaml b/oci/metrics-proxy/image.yaml new file mode 100644 index 00000000..562e2284 --- /dev/null +++ b/oci/metrics-proxy/image.yaml @@ -0,0 +1,18 @@ +version: 1 +upload: + - source: canonical/metrics-proxy-rock + commit: 66763a5703df2e3175b87c0da69b29103da47169 + directory: "0.1.1" + release: + 0.1.1-22.04: + end-of-life: "2025-11-27T00:00:00Z" + risks: + - stable + 0.1-22.04: + end-of-life: "2025-11-27T00:00:00Z" + risks: + - stable + 0-22.04: + end-of-life: "2025-11-27T00:00:00Z" + risks: + - stable \ No newline at end of file diff --git a/oci/mock-rock/_releases.json b/oci/mock-rock/_releases.json index 62d7445f..441aab99 100644 --- a/oci/mock-rock/_releases.json +++ b/oci/mock-rock/_releases.json @@ -35,31 +35,31 @@ "1.1-22.04": { "end-of-life": "2030-05-01T00:00:00Z", "candidate": { - "target": "966" + "target": "987" }, "beta": { - "target": "966" + "target": "987" }, "edge": { - "target": "966" + "target": "987" } }, "1-22.04": { "end-of-life": "2030-05-01T00:00:00Z", "candidate": { - "target": "966" + "target": "987" }, "beta": { - "target": "966" + "target": "987" }, "edge": { - "target": "966" + "target": "987" } }, "1.2-22.04": { "end-of-life": "2030-05-01T00:00:00Z", "beta": { - "target": "967" + "target": "988" }, "edge": { "target": "1.2-22.04_beta" diff --git a/oci/python/_releases.json b/oci/python/_releases.json index c53e77ff..be533d2b 100644 --- a/oci/python/_releases.json +++ b/oci/python/_releases.json @@ -1,47 +1,47 @@ { "3.8-20.04": { "edge": { - "target": "43" + "target": "54" }, "end-of-life": "2025-03-31T00:00:00Z", "stable": { - "target": "43" + "target": "54" }, "candidate": { - "target": "43" + "target": "54" }, "beta": { - "target": "43" + "target": "54" } }, "3.12-24.04": { "end-of-life": "2029-03-31T00:00:00Z", "edge": { - "target": "48" + "target": "56" }, "stable": { - "target": "48" + "target": "56" }, "candidate": { - "target": "48" + "target": "56" }, "beta": { - "target": "48" + "target": "56" } }, "3.10-22.04": { "end-of-life": "2027-03-31T00:00:00Z", "stable": { - "target": "38" + "target": "55" }, "candidate": { - "target": "38" + "target": "55" }, "beta": { - "target": "38" + "target": "55" }, "edge": { - "target": "38" + "target": "55" } } } \ No newline at end of file diff --git a/src/image/prepare_single_image_build_matrix.py b/src/image/prepare_single_image_build_matrix.py index 52432701..c144b205 100755 --- a/src/image/prepare_single_image_build_matrix.py +++ b/src/image/prepare_single_image_build_matrix.py @@ -107,11 +107,20 @@ def filter_eol_tracks(build: dict[str, Any]) -> dict[str, Any]: def filter_eol_builds(builds: list[dict[str, Any]]) -> list[dict[str, Any]]: - """Remove any builds with no tracks specified.""" - # remove any end of life tracks - builds = [filter_eol_tracks(build) for build in builds] + """Remove any builds with eol tracks.""" - return [build for build in builds if len(build["release"])] + # if no release exists and therefore no eol is specified, do nothing + non_release_builds = [build for build in builds if "release" not in build] + + # if we have release info, then filter based on eol + release_builds = [ + filtered_build + for build in builds + if "release" in build + and (filtered_build := filter_eol_tracks(build))["release"] + ] + + return non_release_builds + release_builds def write_revision_data(data_dir: Path, build: dict[str, Any]): @@ -157,7 +166,7 @@ def write_github_output( """Write script result to GITHUB_OUTPUT.""" outputs = { "build-matrix": {"include": builds}, - "release-to": release_to, + "release-to": "true" if release_to else "", "revision-data-dir": str(revision_data_dir), } with GithubOutput() as github_output: @@ -221,16 +230,21 @@ def main(): f"Generating matrix for following builds: \n {json.dumps(builds, indent=4)}" ) + # trigger a release if specified in the image_trigger root + release = "release" in image_trigger + for build in builds: write_revision_data(args.revision_data_dir, build) - # the workflow GH matrix has a problem parsing nested JSON dicts - # so let's remove this field since we don't need it for the builds - del build["release"] + if "release" in build: + # trigger a release if specified in any of the builds + release = True - release_to = "true" if "release" in image_trigger else "" + # the workflow GH matrix has a problem parsing nested JSON dicts + # so let's remove this field since we don't need it for the builds themselves + del build["release"] - write_github_output(release_to, builds, args.revision_data_dir) + write_github_output(release, builds, args.revision_data_dir) if __name__ == "__main__": diff --git a/tests/data/image_all_eol_tracks.yaml b/tests/data/image_all_eol_tracks.yaml new file mode 100644 index 00000000..2a0550b3 --- /dev/null +++ b/tests/data/image_all_eol_tracks.yaml @@ -0,0 +1,37 @@ +version: 1 + +upload: + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.0 + release: + 1.0-22.04: + end-of-life: "2020-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.1 + release: + 1.1-22.04: + end-of-life: "2000-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + 1-22.04: + end-of-life: "2000-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.2 + release: + 1.2-22.04: + end-of-life: "2000-05-01T00:00:00Z" + risks: + - beta diff --git a/tests/data/image_all_eol_tracks_with_release.yaml b/tests/data/image_all_eol_tracks_with_release.yaml new file mode 100644 index 00000000..b92f7b27 --- /dev/null +++ b/tests/data/image_all_eol_tracks_with_release.yaml @@ -0,0 +1,45 @@ +version: 1 + +release: + latest: + end-of-life: "2030-05-01T00:00:00Z" + candidate: 1.2-22.04_beta + test: + end-of-life: "2030-05-01T00:00:00Z" + beta: 1.1-22.04_beta + +upload: + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.0 + release: + 1.0-22.04: + end-of-life: "2020-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.1 + release: + 1.1-22.04: + end-of-life: "2000-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + 1-22.04: + end-of-life: "2000-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.2 + release: + 1.2-22.04: + end-of-life: "2000-05-01T00:00:00Z" + risks: + - beta diff --git a/tests/data/image_no_track_releases.yaml b/tests/data/image_no_track_releases.yaml new file mode 100644 index 00000000..941bcd17 --- /dev/null +++ b/tests/data/image_no_track_releases.yaml @@ -0,0 +1,14 @@ +version: 1 + +upload: + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.0 + + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.1 + + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.2 diff --git a/tests/data/image_single_track_release.yaml b/tests/data/image_single_track_release.yaml new file mode 100644 index 00000000..47efa36b --- /dev/null +++ b/tests/data/image_single_track_release.yaml @@ -0,0 +1,19 @@ +version: 1 + +upload: + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.0 + + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.1 + + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.2 + release: + 1.2-22.04: + end-of-life: "2030-05-01T00:00:00Z" + risks: + - beta diff --git a/tests/data/image_with_release.yaml b/tests/data/image_with_release.yaml new file mode 100644 index 00000000..72382b32 --- /dev/null +++ b/tests/data/image_with_release.yaml @@ -0,0 +1,45 @@ +version: 1 + +release: + latest: + end-of-life: "2030-05-01T00:00:00Z" + candidate: 1.2-22.04_beta + test: + end-of-life: "2030-05-01T00:00:00Z" + beta: 1.1-22.04_beta + +upload: + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.0 + release: + 1.0-22.04: + end-of-life: "2024-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.1 + release: + 1.1-22.04: + end-of-life: "2030-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + 1-22.04: + end-of-life: "2030-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.2 + release: + 1.2-22.04: + end-of-life: "2030-05-01T00:00:00Z" + risks: + - beta diff --git a/tests/data/image_without_release.yaml b/tests/data/image_without_release.yaml new file mode 100644 index 00000000..488174c5 --- /dev/null +++ b/tests/data/image_without_release.yaml @@ -0,0 +1,37 @@ +version: 1 + +upload: + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.0 + release: + 1.0-22.04: + end-of-life: "2024-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.1 + release: + 1.1-22.04: + end-of-life: "2030-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + 1-22.04: + end-of-life: "2030-05-01T00:00:00Z" + risks: + - candidate + - edge + - beta + - source: "canonical/rocks-toolbox" + commit: 17916dd5de270e61a6a3fd3f4661a6413a50fd6f + directory: mock_rock/1.2 + release: + 1.2-22.04: + end-of-life: "2030-05-01T00:00:00Z" + risks: + - beta diff --git a/tests/integration/test_prepare_single_image_build_matrix.py b/tests/integration/test_prepare_single_image_build_matrix.py new file mode 100644 index 00000000..95082977 --- /dev/null +++ b/tests/integration/test_prepare_single_image_build_matrix.py @@ -0,0 +1,86 @@ +# from pathlib import Path +# import pytest + +import json +import re +import shutil +import sys +from pathlib import Path + +import pytest + +from src.image.prepare_single_image_build_matrix import \ + main as prepare_build_matrix + +from .. import DATA_DIR + + +@pytest.fixture +def prep_execution(tmpdir, monkeypatch, request): + + image_trigger_sample = getattr(request, "param", None) + + # configure files/env requried for the test + github_output = tmpdir / "github_output" + monkeypatch.setenv("GITHUB_OUTPUT", str(github_output)) + + revision_data_dir = tmpdir / "revision-data" + revision_data_dir.mkdir() + + oci_trigger_dir = tmpdir / "image_trigger" + oci_trigger_dir.mkdir() + shutil.copy( + image_trigger_sample, + oci_trigger_dir / "image.yaml", + ) + + # patch the arv for the test. script.py can be anything + args = ( + f"--oci-path {oci_trigger_dir} --revision-data-dir {revision_data_dir}".split( + " " + ) + ) + monkeypatch.setattr(sys, "argv", ["script.py"] + args) + + return revision_data_dir, github_output + + +@pytest.mark.parametrize( + "prep_execution, expected_release_to, expected_release_count", + [ + (DATA_DIR / "image_all_eol_tracks_with_release.yaml", True, 0), + (DATA_DIR / "image_all_eol_tracks.yaml", False, 0), + (DATA_DIR / "image_no_track_releases.yaml", False, 0), + (DATA_DIR / "image_single_track_release.yaml", True, 1), + (DATA_DIR / "image_with_release.yaml", True, 3), + (DATA_DIR / "image_without_release.yaml", True, 3), + ], + indirect=["prep_execution"], +) +def test_release_to(prep_execution, expected_release_to, expected_release_count): + """Test state of release-to in github output after running prepare_single_image_build_matrix""" + revision_data_dir, github_output = prep_execution + + # run main from prepare_single_image_build_matrix + prepare_build_matrix() + + github_output_content = github_output.read_text("utf8") + + assert re.search( + f'^release-to={"true" if expected_release_to else ""}$', + github_output_content, + re.M, + ), "Invalid release-to value" + + revision_files = Path(revision_data_dir).glob("*") + + release_count = 0 + + for file in revision_files: + revision_data = json.loads(file.read_text()) + if release_list := revision_data.get("release"): + release_count += len(release_list) + + assert ( + expected_release_count == release_count + ), "Invalid number of builds to release"