apiVersion: tekton.dev/v1 kind: Task metadata: name: {{ .AppName }}-update-manifest namespace: tekton-pipelines spec: stepTemplate: 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: "" 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) 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_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" git clone --branch "$MANIFESTS_BRANCH" "$MANIFESTS_URL" /tmp/manifests 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 ] || [ "$ENVIRONMENT" = production ]; then app_dir="apps/$ENVIRONMENT/$APP_NAME" [ -f "$app_dir/release.yaml" ] || fail sed -i -E "s|^([[:space:]]*tag:).*|\1 $TAG|" "$app_dir/release.yaml" 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" git push origin "$MANIFESTS_BRANCH" --- apiVersion: tekton.dev/v1 kind: Pipeline metadata: name: {{ .AppName }} namespace: tekton-pipelines spec: params: - name: git-url default: {{ quote .AppRepoURL }} - name: git-revision default: {{ quote .AppRepoRef }} - name: branch default: {{ quote .AppRepoRef }} - name: event-type default: push - name: event-action default: "" - name: pr-number default: "" - name: image default: {{ quote .ImageRepository }} - name: manifests-url default: {{ quote .ManifestsURL }} - name: manifests-branch default: {{ quote .ManifestsBranch }} workspaces: - name: source taskRunTemplate: serviceAccountName: tekton-delivery tasks: - name: build-and-push when: - input: $(params.event-action) operator: notin values: [closed] taskRef: name: maidn-node-static-image params: - name: url value: {{ quote .AppRepoURL }} - name: revision value: $(params.git-revision) - name: image value: $(params.image) - name: output-directory value: {{ quote .BuildOutputDirectory }} - name: build-configuration value: {{ quote .BuildConfiguration }} workspaces: - name: source workspace: source - name: update-preview runAfter: [build-and-push] when: - input: $(params.event-type) operator: in values: [pull_request] - input: $(params.event-action) operator: in values: [opened, reopened, synchronize] taskRef: name: {{ .AppName }}-update-manifest params: - name: manifests-url value: $(params.manifests-url) - name: manifests-branch value: $(params.manifests-branch) - name: app-name value: {{ quote .AppName }} - name: app-repository value: {{ quote .AppRepository }} - 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: {{ quote .AppRepoURL }} - name: app-revision value: $(params.git-revision) - name: update-staging runAfter: [build-and-push] when: - input: $(params.event-type) operator: in values: [push] - input: $(params.branch) operator: in values: [{{ quote .AppRepoRef }}] taskRef: name: {{ .AppName }}-update-manifest params: - name: manifests-url value: $(params.manifests-url) - name: manifests-branch value: $(params.manifests-branch) - name: app-name value: {{ quote .AppName }} - name: app-repository value: {{ quote .AppRepository }} - name: image value: $(params.image) - name: tag value: $(params.git-revision) - name: environment value: staging - name: promote-production runAfter: [build-and-push] when: - input: $(params.event-type) operator: in values: [promotion] - input: $(params.branch) operator: in values: [{{ quote .ProductionBranch }}] taskRef: name: {{ .AppName }}-update-manifest params: - name: manifests-url value: $(params.manifests-url) - name: manifests-branch value: $(params.manifests-branch) - name: app-name value: {{ quote .AppName }} - name: app-repository value: {{ quote .AppRepository }} - name: image value: $(params.image) - name: tag value: $(params.git-revision) - name: environment value: production - 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: {{ quote .AppName }} - name: pr-number value: $(params.pr-number) - name: app-repository value: {{ quote .AppRepository }}