diff --git a/.tekton/kustomization.yaml b/.tekton/kustomization.yaml new file mode 100644 index 0000000..db99cd7 --- /dev/null +++ b/.tekton/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - pipeline.yaml diff --git a/.tekton/pipeline.yaml b/.tekton/pipeline.yaml new file mode 100644 index 0000000..270dab5 --- /dev/null +++ b/.tekton/pipeline.yaml @@ -0,0 +1,831 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: maidn-e2e-angular-update-manifest + namespace: tekton-pipelines +spec: + stepTemplate: + env: + - name: HOME + value: /tekton/home + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] + seccompProfile: + type: RuntimeDefault + params: + - name: manifests-url + - name: manifests-branch + - name: app-name + - name: app-repository + - name: image + - name: tag + - name: environment + - name: pr-number + default: "" + - name: app-url + default: "" + - name: app-revision + default: "" + - name: forgejo-base-url + default: "" + - name: forgejo-owner + default: "" + - name: manifests-repo + default: "" + steps: + - name: update + image: alpine/git:2.47.2 + env: + - name: MANIFESTS_URL + value: $(params.manifests-url) + - name: MANIFESTS_BRANCH + value: $(params.manifests-branch) + - name: APP_NAME + value: $(params.app-name) + - name: APP_REPOSITORY + value: $(params.app-repository) + - name: IMAGE + value: $(params.image) + - name: TAG + value: $(params.tag) + - name: ENVIRONMENT + value: $(params.environment) + - name: PR_NUMBER + value: $(params.pr-number) + - name: APP_URL + value: $(params.app-url) + - name: APP_REVISION + value: $(params.app-revision) + - name: FORGEJO_BASE_URL + value: $(params.forgejo-base-url) + - name: FORGEJO_OWNER + value: $(params.forgejo-owner) + - name: MANIFESTS_REPO + value: $(params.manifests-repo) + script: | + #!/bin/sh + set -eu + fail() { exit 1; } + valid_name() { case "$1" in ''|*[!a-z0-9-]*|-*|*-) fail ;; esac; } + valid_revision() { case "$1" in [A-Za-z0-9]*) ;; *) fail ;; esac; case "$1" in *[!A-Za-z0-9._/-]*|*..*|*//*|*/) fail ;; esac; } + valid_commit() { [ "${#1}" -eq 40 ] || fail; case "$1" in *[!0-9a-fA-F]*) fail ;; esac; } + valid_url() { case "$1" in https://*/*.git) ;; *) fail ;; esac; case "$1" in *[@?#]*) fail ;; esac; } + valid_repository() { case "$1" in */*) ;; *) fail ;; esac; case "$1" in *..*|*//*|/*|*/) fail ;; esac; } + valid_repository_part() { case "$1" in ''|*[!A-Za-z0-9._-]*|.*|*.) fail ;; esac; } + valid_forgejo_base_url() { case "$1" in https://*) ;; *) fail ;; esac; host=${1#https://}; case "$host" in *:*) name=${host%:*}; port=${host##*:}; case "$port" in ''|*[!0-9]*) fail ;; esac ;; *) name=$host ;; esac; case "$name" in ''|*[!A-Za-z0-9.-]*|.*|*.) fail ;; esac; } + valid_pr_number() { case "$1" in [1-9]*) ;; *) fail ;; esac; case "$1" in *[!0-9]*) fail ;; esac; [ $((${#APP_NAME} + ${#1} + 4)) -le 63 ] || fail; } + valid_name "$APP_NAME" + valid_url "$MANIFESTS_URL" + valid_revision "$MANIFESTS_BRANCH" + valid_repository "$APP_REPOSITORY" + valid_commit "$TAG" + if [ "$ENVIRONMENT" = production ]; then + valid_forgejo_base_url "$FORGEJO_BASE_URL" + valid_repository_part "$FORGEJO_OWNER" + valid_repository_part "$MANIFESTS_REPO" + [ "$MANIFESTS_URL" = "$FORGEJO_BASE_URL/$FORGEJO_OWNER/$MANIFESTS_REPO.git" ] || fail + PROMOTION_BRANCH="maidn/promotion-$APP_NAME-$TAG" + if git ls-remote --exit-code "$MANIFESTS_URL" "refs/heads/$PROMOTION_BRANCH" >/dev/null 2>&1; then + git clone --branch "$PROMOTION_BRANCH" "$MANIFESTS_URL" /tmp/manifests + else + git clone --branch "$MANIFESTS_BRANCH" "$MANIFESTS_URL" /tmp/manifests + git -C /tmp/manifests checkout -b "$PROMOTION_BRANCH" + fi + else + git clone --branch "$MANIFESTS_BRANCH" "$MANIFESTS_URL" /tmp/manifests + fi + cd /tmp/manifests + if [ "$ENVIRONMENT" = preview ]; then + valid_pr_number "$PR_NUMBER" + valid_url "$APP_URL" + valid_revision "$APP_REVISION" + app_dir="apps/previews/$APP_NAME-pr-$PR_NUMBER" + marker="$app_dir/ownership.yaml" + if [ -e "$app_dir" ]; then + [ -d "$app_dir" ] && [ ! -L "$app_dir" ] && [ -f "$marker" ] && [ ! -L "$marker" ] || fail + expected_marker=$(mktemp) + trap 'rm -f "$expected_marker"' EXIT + cat > "$expected_marker" < "$marker" < "$app_dir/namespace.yaml" < "$app_dir/release.yaml" < "$app_dir/kustomization.yaml" </dev/null || printf ' - %s-pr-%s\n' "$APP_NAME" "$PR_NUMBER" >> "$root" + elif [ "$ENVIRONMENT" = staging ]; then + app_dir="apps/staging/$APP_NAME" + root=apps/staging/kustomization.yaml + if [ -e "$app_dir/release.yaml" ]; then + [ -d "$app_dir" ] && [ ! -L "$app_dir" ] && [ -f "$app_dir/release.yaml" ] && [ ! -L "$app_dir/release.yaml" ] || fail + sed -i -E "s|^([[:space:]]*tag:).*|\1 $TAG|" "$app_dir/release.yaml" + grep -qxF " namespace: staging" "$app_dir/release.yaml" || sed -i "/^ name: $APP_NAME$/a\ namespace: staging" "$app_dir/release.yaml" + grep -qxF " namespace: staging" "$app_dir/release.yaml" || fail + else + [ ! -e "$app_dir" ] || fail + mkdir -p "$app_dir" + cat > "$app_dir/release.yaml" < "$app_dir/kustomization.yaml" < "$root" </dev/null || printf ' - %s\n' "$APP_NAME" >> "$root" + fi + elif [ "$ENVIRONMENT" = production ]; then + app_dir="apps/production/$APP_NAME" + root=apps/production/kustomization.yaml + if [ -e "$app_dir" ]; then + [ -d "$app_dir" ] && [ ! -L "$app_dir" ] || fail + fi + mkdir -p "$app_dir" + for file in "$app_dir/release.yaml" "$app_dir/kustomization.yaml"; do + [ ! -e "$file" ] || { [ -f "$file" ] && [ ! -L "$file" ]; } || fail + done + cat > "$app_dir/release.yaml" < "$app_dir/kustomization.yaml" < "$root" </dev/null || printf ' - %s\n' "$APP_NAME" >> "$root" + else + fail + fi + git config user.name Maidn + git config user.email maidn@free-maidn.com + git add apps + git diff --cached --quiet || git commit -m "chore: deploy $APP_NAME $TAG" + if [ "$ENVIRONMENT" = production ]; then + git push origin "HEAD:$PROMOTION_BRANCH" + credentials=$(printf 'url=%s\n\n' "$MANIFESTS_URL" | GIT_TERMINAL_PROMPT=0 git credential fill) + forgejo_user=$(printf '%s\n' "$credentials" | sed -n 's/^username=//p') + forgejo_password=$(printf '%s\n' "$credentials" | sed -n 's/^password=//p') + unset credentials + [ -n "$forgejo_user" ] && [ -n "$forgejo_password" ] || fail + forgejo_auth=$(printf '%s:%s' "$forgejo_user" "$forgejo_password" | base64 | tr -d '\n') + unset forgejo_user forgejo_password + pr_endpoint="$FORGEJO_BASE_URL/api/v1/repos/$FORGEJO_OWNER/$MANIFESTS_REPO/pulls" + pr_query="$pr_endpoint?state=open&head=$FORGEJO_OWNER%3A$PROMOTION_BRANCH" + pr_response=$(mktemp) + pr_body=$(mktemp) + trap 'rm -f "$pr_response" "$pr_body"' EXIT + open_pr_count() { + grep -q '^[[:space:]]*\[' "$pr_response" || fail + grep -o '"number"[[:space:]]*:[[:space:]]*[0-9][0-9]*' "$pr_response" | wc -l | tr -d ' ' + } + wget -q -O "$pr_response" --header="Authorization: Basic $forgejo_auth" "$pr_query" || fail + case "$(open_pr_count)" in + 0) + printf '{"title":"chore: promote %s %s","head":"%s","base":"%s"}' "$APP_NAME" "$TAG" "$PROMOTION_BRANCH" "$MANIFESTS_BRANCH" > "$pr_body" + wget -q -O "$pr_response" --header="Authorization: Basic $forgejo_auth" --header="Content-Type: application/json" --post-file "$pr_body" "$pr_endpoint" || true + wget -q -O "$pr_response" --header="Authorization: Basic $forgejo_auth" "$pr_query" || fail + [ "$(open_pr_count)" = 1 ] || fail + ;; + 1) ;; + *) fail ;; + esac + promotion_pr_number=$(grep -o '"number"[[:space:]]*:[[:space:]]*[0-9][0-9]*' "$pr_response" | sed -n '1s/.*:[[:space:]]*//p') + valid_pr_number "$promotion_pr_number" + printf 'Promotion PR opened or updated: %s/%s/%s/pulls/%s\n' "$FORGEJO_BASE_URL" "$FORGEJO_OWNER" "$MANIFESTS_REPO" "$promotion_pr_number" + unset forgejo_auth + else + git push origin "$MANIFESTS_BRANCH" + fi +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: maidn-e2e-angular-wait-delivery + namespace: tekton-pipelines +spec: + params: + - name: app-name + - name: environment + - name: image + - name: tag + - name: pr-number + default: "" + results: + - name: preview-url + description: Verified preview or staging HTTPRoute URL. + stepTemplate: + env: + - name: HOME + value: /tmp + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] + seccompProfile: + type: RuntimeDefault + steps: + - name: wait-for-traffic + image: alpine/k8s:1.33.4 + env: + - name: APP_NAME + value: $(params.app-name) + - name: ENVIRONMENT + value: $(params.environment) + - name: PR_NUMBER + value: $(params.pr-number) + - name: IMAGE + value: $(params.image) + - name: TAG + value: $(params.tag) + - name: RESULT_PATH + value: $(results.preview-url.path) + script: | + #!/bin/sh + set -eu + fail() { exit 1; } + valid_app() { case "$1" in ''|*[!a-z0-9-]*|-*|*-) fail ;; esac; [ "${#1}" -le 47 ] || fail; } + valid_pr() { case "$1" in [1-9]*) ;; *) fail ;; esac; case "$1" in *[!0-9]*) fail ;; esac; } + valid_image() { case "$1" in ''|/*|*/|*..*|*//*|*[!A-Za-z0-9._/:-]*) fail ;; esac; } + valid_tag() { [ "${#1}" -eq 40 ] || fail; case "$1" in *[!0-9a-fA-F]*) fail ;; esac; } + valid_host() { case "$1" in ''|.*|*.) fail ;; esac; case "$1" in *[!A-Za-z0-9.-]*) fail ;; esac; } + valid_app "$APP_NAME" + valid_image "$IMAGE" + valid_tag "$TAG" + case "$ENVIRONMENT" in + preview) + valid_pr "$PR_NUMBER" + namespace="$APP_NAME-pr-$PR_NUMBER" + ;; + staging) namespace=staging ;; + *) fail ;; + esac + attempts=120 + while :; do + deployed_image=$(kubectl -n "$namespace" get "deployment/$APP_NAME" -o jsonpath='{.spec.template.spec.containers[0].image}' 2>/dev/null || true) + [ "$deployed_image" = "$IMAGE:$TAG" ] && break + attempts=$((attempts - 1)) + [ "$attempts" -gt 0 ] || fail + sleep 5 + done + kubectl -n "$namespace" rollout status "deployment/$APP_NAME" --timeout=600s + kubectl -n "$namespace" wait --for=condition=Available "deployment/$APP_NAME" --timeout=600s + kubectl -n "$namespace" wait --for=jsonpath='{.status.parents[0].conditions[?(@.type=="Accepted")].status}'=True "httproute/$APP_NAME" --timeout=600s + host=$(kubectl -n "$namespace" get "httproute/$APP_NAME" -o jsonpath='{.spec.hostnames[0]}') + valid_host "$host" + url="https://$host" + attempts=12 + while ! wget -q --spider --timeout=10 "$url" >/dev/null 2>&1; do + attempts=$((attempts - 1)) + [ "$attempts" -gt 0 ] || fail + sleep 5 + done + printf '%s' "$url" > "$RESULT_PATH" +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: maidn-e2e-angular-report-delivery + namespace: tekton-pipelines +spec: + params: + - name: app-name + - name: app-repository + - name: pr-number + - name: event-action + - name: pipeline-run + - name: clone-status + - name: build-status + - name: push-status + - name: update-status + - name: readiness-status + - name: cleanup-status + volumes: + - name: delivery-status + emptyDir: {} + stepTemplate: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + allowPrivilegeEscalation: false + capabilities: + drop: [ALL] + seccompProfile: + type: RuntimeDefault + steps: + - name: read-preview-url + image: alpine/k8s:1.33.4 + env: + - name: APP_NAME + value: $(params.app-name) + - name: PR_NUMBER + value: $(params.pr-number) + - name: EVENT_ACTION + value: $(params.event-action) + - name: READINESS_STATUS + value: $(params.readiness-status) + volumeMounts: + - name: delivery-status + mountPath: /delivery + script: | + #!/bin/sh + set -eu + fail() { exit 1; } + valid_app() { case "$1" in ''|*[!a-z0-9-]*|-*|*-) fail ;; esac; [ "${#1}" -le 47 ] || fail; } + valid_pr() { case "$1" in [1-9]*) ;; *) fail ;; esac; case "$1" in *[!0-9]*) fail ;; esac; } + valid_host() { case "$1" in ''|.*|*.) fail ;; esac; case "$1" in *[!A-Za-z0-9.-]*) fail ;; esac; } + [ "$EVENT_ACTION" = closed ] && exit 0 + [ "$READINESS_STATUS" = Succeeded ] || exit 0 + valid_app "$APP_NAME" + valid_pr "$PR_NUMBER" + host=$(kubectl -n "$APP_NAME-pr-$PR_NUMBER" get "httproute/$APP_NAME" -o jsonpath='{.spec.hostnames[0]}') + valid_host "$host" + printf 'https://%s' "$host" > /delivery/preview-url + - name: update-pr-comment + image: python:3.13-alpine + env: + - name: FORGEJO_BASE_URL + value: "https://git.pingu.pw" + - name: APP_NAME + value: $(params.app-name) + - name: APP_REPOSITORY + value: $(params.app-repository) + - name: PR_NUMBER + value: $(params.pr-number) + - name: EVENT_ACTION + value: $(params.event-action) + - name: PIPELINE_RUN + value: $(params.pipeline-run) + - name: CLONE_STATUS + value: $(params.clone-status) + - name: BUILD_STATUS + value: $(params.build-status) + - name: PUSH_STATUS + value: $(params.push-status) + - name: UPDATE_STATUS + value: $(params.update-status) + - name: READINESS_STATUS + value: $(params.readiness-status) + - name: CLEANUP_STATUS + value: $(params.cleanup-status) + - name: FORGEJO_DELIVERY_TOKEN + valueFrom: + secretKeyRef: + name: forgejo-delivery-status + key: token + - name: TEKTON_DASHBOARD_URL + valueFrom: + configMapKeyRef: + name: maidn-preview-delivery-config + key: tekton-dashboard-url + optional: true + volumeMounts: + - name: delivery-status + mountPath: /delivery + script: | + import json + import os + import re + import sys + from pathlib import Path + from urllib.parse import quote, urlsplit + from urllib.request import Request, urlopen + + marker = "" + statuses = {"Succeeded", "Failed", "None", "Skipped", "Cancelled", "Unknown", "Pending"} + + def fail(): + raise ValueError + + def origin(value): + parsed = urlsplit(value) + if parsed.scheme != "https" or not parsed.netloc or parsed.username or parsed.password or parsed.path or parsed.query or parsed.fragment: + fail() + if not re.fullmatch(r"[A-Za-z0-9.-]+(?::[0-9]{1,5})?", parsed.netloc): + fail() + return value + + def status(name): + value = os.environ.get(name, "Unknown") + return value if value in statuses else "Unknown" + + def request(method, endpoint, payload=None): + data = None if payload is None else json.dumps(payload).encode() + req = Request(endpoint, data=data, method=method) + req.add_header("Authorization", "token " + token) + req.add_header("Content-Type", "application/json") + with urlopen(req, timeout=15) as response: + return json.load(response) if response.length != 0 else None + + try: + base = origin(os.environ["FORGEJO_BASE_URL"]) + app = os.environ["APP_NAME"] + repository = os.environ["APP_REPOSITORY"] + pr = os.environ["PR_NUMBER"] + run = os.environ["PIPELINE_RUN"] + action = os.environ["EVENT_ACTION"] + token = os.environ["FORGEJO_DELIVERY_TOKEN"] + if not re.fullmatch(r"[a-z0-9](?:[a-z0-9-]{0,45}[a-z0-9])?", app) or not re.fullmatch(r"[1-9][0-9]{0,8}", pr) or not re.fullmatch(r"[a-z0-9](?:[a-z0-9.-]{0,61}[a-z0-9])?", run) or action not in {"opened", "reopened", "synchronize", "closed"} or not token: + fail() + owner, repo = repository.split("/", 1) + if not all(re.fullmatch(r"[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?", part) and ".." not in part for part in (owner, repo)): + fail() + task_status = {name: status(name) for name in ("CLONE_STATUS", "BUILD_STATUS", "PUSH_STATUS", "UPDATE_STATUS", "READINESS_STATUS", "CLEANUP_STATUS")} + if action == "closed": + delivery = "closed" + preview = "Preview cleanup requested." + elif task_status["READINESS_STATUS"] == "Succeeded" and task_status["UPDATE_STATUS"] == "Succeeded": + delivery = "ready" + preview_url = Path("/delivery/preview-url").read_text() if Path("/delivery/preview-url").is_file() else "" + parsed_preview = urlsplit(preview_url) + if parsed_preview.scheme != "https" or not re.fullmatch(r"[A-Za-z0-9.-]+", parsed_preview.netloc) or parsed_preview.path or parsed_preview.query or parsed_preview.fragment: + fail() + preview = "Preview: " + preview_url + else: + delivery = "failed" + preview = "Preview unavailable." + dashboard = os.environ.get("TEKTON_DASHBOARD_URL", "").strip() + run_text = "PipelineRun: `" + run + "`" + if dashboard: + dashboard = origin(dashboard.rstrip("/")) + run_text += " ([details](" + dashboard + "/#/pipelineruns/tekton-pipelines/" + quote(run, safe="") + "))" + summary = ", ".join(name.removesuffix("_STATUS").lower() + "=" + value for name, value in task_status.items()) + body = "\n".join((marker, "## Maidn delivery", "Status: **" + delivery + "**", preview, run_text, "Summary: " + summary)) + endpoint = base + "/api/v1/repos/" + quote(owner, safe="") + "/" + quote(repo, safe="") + "/issues/" + pr + "/comments" + comments = request("GET", endpoint + "?limit=100") + matches = [comment for comment in comments if marker in comment.get("body", "")] + if len(matches) > 1: + fail() + if matches: + request("PATCH", base + "/api/v1/repos/" + quote(owner, safe="") + "/" + quote(repo, safe="") + "/issues/comments/" + str(matches[0]["id"]), {"body": body}) + else: + request("POST", endpoint, {"body": body}) + except Exception: + sys.exit("delivery status update failed") +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: maidn-e2e-angular + namespace: tekton-pipelines +spec: + params: + - name: git-url + default: "https://git.pingu.pw/Maidn/maidn-e2e-angular.git" + - name: git-revision + default: "main" + - name: branch + default: "main" + - name: event-type + default: push + - name: event-action + default: "" + - name: pr-number + default: "" + - name: image + default: "registry.pingu.pw/test-org-2/maidn-e2e-angular" + - name: manifests-url + default: "https://git.pingu.pw/test-org-2/cicd-deployment-manifests.git" + - name: manifests-branch + default: "main" + - name: forgejo-base-url + default: "https://git.pingu.pw" + - name: forgejo-owner + default: "test-org-2" + - name: manifests-repo + default: "cicd-deployment-manifests" + tasks: + - name: build-layer + when: + - input: $(params.event-action) + operator: notin + values: [closed] + taskRef: + name: maidn-node-static-image + params: + - name: url + value: "https://git.pingu.pw/Maidn/maidn-e2e-angular.git" + - name: revision + value: $(params.git-revision) + - name: image + value: $(params.image) + + - name: output-directory + value: "dist/maidn-e2e-angular" + - name: build-configuration + value: "ci" + + - name: update-preview + runAfter: [build-layer] + when: + - input: $(params.event-type) + operator: in + values: [pull_request] + - input: $(params.event-action) + operator: in + values: [opened, reopened, synchronize] + taskRef: + name: maidn-e2e-angular-update-manifest + params: + - name: manifests-url + value: $(params.manifests-url) + - name: manifests-branch + value: $(params.manifests-branch) + - name: app-name + value: "maidn-e2e-angular" + - name: app-repository + value: "Maidn/maidn-e2e-angular" + - name: image + value: $(params.image) + - name: tag + value: $(params.git-revision) + - name: environment + value: preview + - name: pr-number + value: $(params.pr-number) + - name: app-url + value: "https://git.pingu.pw/Maidn/maidn-e2e-angular.git" + - name: app-revision + value: $(params.git-revision) + - name: update-staging + runAfter: [build-layer] + when: + - input: $(params.event-type) + operator: in + values: [push] + - input: $(params.branch) + operator: in + values: ["main"] + taskRef: + name: maidn-e2e-angular-update-manifest + params: + - name: manifests-url + value: $(params.manifests-url) + - name: manifests-branch + value: $(params.manifests-branch) + - name: app-name + value: "maidn-e2e-angular" + - name: app-repository + value: "Maidn/maidn-e2e-angular" + - name: image + value: $(params.image) + - name: tag + value: $(params.git-revision) + - name: environment + value: staging + - name: wait-preview + runAfter: [update-preview] + when: + - input: $(params.event-type) + operator: in + values: [pull_request] + - input: $(params.event-action) + operator: in + values: [opened, reopened, synchronize] + taskRef: + name: maidn-e2e-angular-wait-delivery + params: + - name: app-name + value: "maidn-e2e-angular" + - name: environment + value: preview + - name: image + value: $(params.image) + - name: tag + value: $(params.git-revision) + - name: pr-number + value: $(params.pr-number) + - name: wait-staging + runAfter: [update-staging] + when: + - input: $(params.event-type) + operator: in + values: [push] + - input: $(params.branch) + operator: in + values: ["main"] + taskRef: + name: maidn-e2e-angular-wait-delivery + params: + - name: app-name + value: "maidn-e2e-angular" + - name: environment + value: staging + - name: image + value: $(params.image) + - name: tag + value: $(params.git-revision) + - name: promote-production + runAfter: [build-layer] + when: + - input: $(params.event-type) + operator: in + values: [promotion] + - input: $(params.branch) + operator: in + values: ["production"] + taskRef: + name: maidn-e2e-angular-update-manifest + params: + - name: manifests-url + value: $(params.manifests-url) + - name: manifests-branch + value: $(params.manifests-branch) + - name: app-name + value: "maidn-e2e-angular" + - name: app-repository + value: "Maidn/maidn-e2e-angular" + - name: image + value: $(params.image) + - name: tag + value: $(params.git-revision) + - name: environment + value: production + - name: forgejo-base-url + value: $(params.forgejo-base-url) + - name: forgejo-owner + value: $(params.forgejo-owner) + - name: manifests-repo + value: $(params.manifests-repo) + - name: cleanup-preview + when: + - input: $(params.event-type) + operator: in + values: [pull_request] + - input: $(params.event-action) + operator: in + values: [closed] + taskRef: + name: maidn-preview-orphan-reconciler + params: + - name: app-name + value: "maidn-e2e-angular" + - name: pr-number + value: $(params.pr-number) + - name: app-repository + value: "Maidn/maidn-e2e-angular" + finally: + - name: report-delivery + when: + - input: $(params.event-type) + operator: in + values: [pull_request] + taskRef: + name: maidn-e2e-angular-report-delivery + params: + - name: app-name + value: "maidn-e2e-angular" + - name: app-repository + value: "Maidn/maidn-e2e-angular" + - name: pr-number + value: $(params.pr-number) + - name: event-action + value: $(params.event-action) + - name: pipeline-run + value: $(context.pipelineRun.name) + - name: clone-status + value: $(tasks.build-layer.status) + - name: build-status + value: $(tasks.build-layer.status) + - name: push-status + value: $(tasks.build-layer.status) + - name: update-status + value: $(tasks.update-preview.status) + - name: readiness-status + value: $(tasks.wait-preview.status) + - name: cleanup-status + value: $(tasks.cleanup-preview.status)