diff --git a/argocd-pr-env-deploy/action.yml b/argocd-pr-env-deploy/action.yml index 891e3e4..f978ed5 100644 --- a/argocd-pr-env-deploy/action.yml +++ b/argocd-pr-env-deploy/action.yml @@ -115,6 +115,13 @@ inputs: description: ArgoCD CLI version installed when missing from the runner. required: false default: v2.13.1 + stacks-dispatch-token: + description: >- + Token used to dispatch mindshub_services' pr-env-stacks.yml for this env + (needs `actions: write` there). Defaults to gh-token. The dispatch is + best-effort: on failure the reconciler's schedule picks the env up. + required: false + default: "" wait-timeout: description: >- Seconds to wait for the env to reach Synced+Healthy before failing. @@ -133,6 +140,7 @@ runs: ARGOCD_AUTH_TOKEN: ${{ inputs.argocd-token }} ARGOCD_VERSION: ${{ inputs.argocd-version }} GH_TOKEN: ${{ inputs.gh-token }} + STACKS_DISPATCH_TOKEN: ${{ inputs.stacks-dispatch-token || inputs.gh-token }} WAIT_TIMEOUT: ${{ inputs.wait-timeout }} run: | set -euo pipefail @@ -246,15 +254,30 @@ runs: # job in this same run — no cross-PR race — but it still gets the # existence check so a failed/skipped build fails HERE, not as an # ImagePullBackOff in the env. - OWN_TAG="development-${OWN_MERGE_SHA}" - if ! ecr_tag_exists "$OWN_SHORT" "$OWN_TAG"; then - echo "::error::ECR image mindsdb-${OWN_SLUG}:${OWN_TAG} not found — did the build job in this run succeed?" - exit 1 + # Repos that publish no image. Their deploy is the git revision alone: + # mindshub_services' pr-env-stacks workflow builds a SAM stack from + # revisions.mindshub_services. Applies to the anchor itself and to + # `Deploys:` links (the revision-only case below). + is_revision_only_repo() { + case "$1" in + mindshub_services) return 0 ;; + *) return 1 ;; + esac + } + + if is_revision_only_repo "$OWN_SHORT"; then + set_args=(--helm-set "revisions.${OWN_SHORT}=${OWN_HEAD_SHA}") + else + OWN_TAG="development-${OWN_MERGE_SHA}" + if ! ecr_tag_exists "$OWN_SHORT" "$OWN_TAG"; then + echo "::error::ECR image mindsdb-${OWN_SLUG}:${OWN_TAG} not found — did the build job in this run succeed?" + exit 1 + fi + set_args=( + --helm-set "tags.${OWN_SHORT}=${OWN_TAG}" + --helm-set "revisions.${OWN_SHORT}=${OWN_HEAD_SHA}" + ) fi - set_args=( - --helm-set "tags.${OWN_SHORT}=${OWN_TAG}" - --helm-set "revisions.${OWN_SHORT}=${OWN_HEAD_SHA}" - ) # Linked PRs resolve in two phases. Phase 1 (inside the process # substitution): parse the body + hit the GitHub API, emitting one @@ -381,19 +404,16 @@ runs: echo "staging:${full}#staging:${full##*/}::" continue fi - # Repos without an image (mindshub_services deploys a SAM - # stack from the revision): head SHA only, no ECR lookup. - case "${full##*/}" in - mindshub_services) - head_sha="$(gh_api "/repos/$full/pulls/$num" | jq -r '.head.sha // ""')" || true - if [ -n "${head_sha:-}" ]; then - echo "revision-only:${full}#${num}:${full##*/}::${head_sha}" - else - echo "unresolved:${full}#${num}:${full##*/}::" - fi - continue - ;; - esac + # Repos without an image: head SHA only, no ECR lookup. + if is_revision_only_repo "${full##*/}"; then + head_sha="$(gh_api "/repos/$full/pulls/$num" | jq -r '.head.sha // ""')" || true + if [ -n "${head_sha:-}" ]; then + echo "revision-only:${full}#${num}:${full##*/}::${head_sha}" + else + echo "unresolved:${full}#${num}:${full##*/}::" + fi + continue + fi # One API call, both SHAs out. merge_commit_sha is null on # unmergeable PRs; those become an unresolved marker (phase 2 # fails the job and comments on the anchor PR). @@ -563,6 +583,26 @@ runs: esac fi + # The env's mindshub_services SAM stack is not an ArgoCD child: the + # pr-env-stacks workflow in mindsdb/mindshub_services deploys it from + # revisions.mindshub_services (just set above). Dispatch it for this + # env now so the stack builds while the env rolls out, instead of on + # that workflow's next scheduled run. Best-effort: a refused dispatch + # (token without actions:write, or the workflow not yet on that + # repo's default branch) is a warning, and the schedule catches up. + # mindshub_services' own CI calls the workflow directly, so skip it. + if [ "$OWN_SHORT" != "mindshub_services" ]; then + if jq -n --arg only "$PARENT_APP" '{ref: "main", inputs: {only: $only}}' \ + | curl -sfX POST -H "Authorization: Bearer $STACKS_DISPATCH_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/mindsdb/mindshub_services/actions/workflows/pr-env-stacks.yml/dispatches" \ + --data @- >/dev/null; then + echo "Dispatched mindshub_services pr-env-stacks.yml for ${PARENT_APP}." + else + echo "::warning::Could not dispatch mindshub_services/pr-env-stacks.yml for ${PARENT_APP}; its schedule will deploy the stack within ~10 minutes." + fi + fi + # Block until the whole env reaches Synced+Healthy with no in-flight # sync, or fail the job after 30m. We wait on the LABEL SET (parent # + every child Application), not just the parent: the parent's