diff --git a/entrypoint.sh b/entrypoint.sh index 2f4247e..a4ad5ed 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -228,6 +228,22 @@ reconcile_managed_comments() { fi } +find_existing_pr_number() { + local pulls_json="" + pulls_json="$(gh api --method GET "repos/${TARGET_REPOSITORY}/pulls?state=open&base=${TARGET_BRANCH}")" + + jq -r \ + --arg repo "${TARGET_REPOSITORY}" \ + --arg branch "${SOURCE_BRANCH}" \ + ' + [ + .[] + | select(.head.ref == $branch) + | select((.head.repo.full_name // "") == $repo) + ][0].number // empty + ' <<< "${pulls_json}" +} + apply_body_limits() { local template_file="$1" local max_body_bytes="$2" @@ -406,7 +422,7 @@ else fi echo -e "\nSetting template..." -PR_NUMBER="$(gh pr list --repo "${TARGET_REPOSITORY}" --state open --base "${TARGET_BRANCH}" --head "${TARGET_OWNER}:${SOURCE_BRANCH}" --json number --jq '.[0].number // empty')" +PR_NUMBER="$(find_existing_pr_number)" if [[ -z "${PR_NUMBER}" ]]; then if [[ -n "${INPUT_TEMPLATE}" ]]; then echo "Template source: input template file" diff --git a/tests/unit/test_existing_pr_lookup.sh b/tests/unit/test_existing_pr_lookup.sh new file mode 100755 index 0000000..87b5a2f --- /dev/null +++ b/tests/unit/test_existing_pr_lookup.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" +SCRIPT_PATH="${SCRIPT_DIR}/../../entrypoint.sh" +TMP_DIR="$(mktemp -d)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +assert_contains() { + local file_path="$1" + local expected="$2" + if ! grep -Fq -- "${expected}" "${file_path}"; then + echo "Assertion failed. Expected to find: ${expected}" >&2 + echo "----- FILE CONTENT -----" >&2 + cat "${file_path}" >&2 + exit 1 + fi +} + +mkdir -p "${TMP_DIR}/bin" +mkdir -p "${TMP_DIR}/repo" + +cat > "${TMP_DIR}/bin/git" <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail + +args=("$@") +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "-C" ]]; then + args=("${args[@]:2}") +fi + +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "config" && "${args[1]}" == "--global" ]]; then + exit 0 +fi + +if [[ "${#args[@]}" -ge 1 && "${args[0]}" == "config" ]]; then + exit 0 +fi + +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "remote" && "${args[1]}" == "set-url" ]]; then + exit 0 +fi + +if [[ "${#args[@]}" -ge 1 && "${args[0]}" == "fetch" ]]; then + exit 0 +fi + +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "rev-parse" && "${args[1]}" == "--is-inside-work-tree" ]]; then + echo "true" + exit 0 +fi + +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "show-ref" ]]; then + last_arg="${args[$((${#args[@]} - 1))]}" + if [[ "${last_arg}" == "refs/remotes/origin/develop" || "${last_arg}" == "refs/remotes/origin/main" ]]; then + exit 0 + fi + exit 1 +fi + +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "rev-parse" ]]; then + last_arg="${args[$((${#args[@]} - 1))]}" + if [[ "${last_arg}" == "origin/develop" ]]; then + echo "bbb222" + exit 0 + fi + if [[ "${last_arg}" == "origin/main" ]]; then + echo "aaa111" + exit 0 + fi +fi + +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "diff" && "${args[1]}" == "--quiet" ]]; then + exit 1 +fi + +if [[ "${#args[@]}" -ge 1 && "${args[0]}" == "diff" ]]; then + echo "M README.md" + exit 0 +fi + +if [[ "${#args[@]}" -ge 1 && "${args[0]}" == "log" ]]; then + echo "stub log" + exit 0 +fi + +if [[ "${#args[@]}" -ge 2 && "${args[0]}" == "symbolic-ref" ]]; then + echo "develop" + exit 0 +fi + +echo "Unsupported git call: $*" >&2 +exit 1 +EOF + +cat > "${TMP_DIR}/bin/gh" <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail + +cmd="$*" + +if [[ "$#" -ge 1 && "$1" == "api" ]]; then + if [[ "${cmd}" == *"repos/owner/repo/pulls?state=open&base=main"* ]]; then + printf '%s\n' '[{"number":88,"head":{"ref":"other-branch","repo":{"full_name":"owner/repo"}}},{"number":123,"head":{"ref":"develop","repo":{"full_name":"owner/repo"}}},{"number":321,"head":{"ref":"develop","repo":{"full_name":"fork/repo"}}}]' + exit 0 + fi + if [[ "${cmd}" == *"repos/owner/repo/pulls/123"* && "${cmd}" == *"--method GET"* ]]; then + echo "OLD BODY" + exit 0 + fi + if [[ "${cmd}" == *"repos/owner/repo/pulls/123"* && "${cmd}" == *"--method PATCH"* ]]; then + echo "https://example.test/pr/123" + exit 0 + fi + if [[ "${cmd}" == *"repos/owner/repo/issues/123/comments"* ]]; then + echo "[]" + exit 0 + fi +fi + +if [[ "$#" -ge 2 && "$1" == "pr" && "$2" == "create" ]]; then + echo "gh pr create should not be called when PR already exists" >&2 + exit 1 +fi + +echo "Unsupported gh call: $*" >&2 +exit 1 +EOF + +cat > "${TMP_DIR}/template.md" <<'EOF' +## Template body from file +EOF + +chmod +x "${TMP_DIR}/bin/git" "${TMP_DIR}/bin/gh" + +LOG_FILE="${TMP_DIR}/run.log" +set +e +PATH="${TMP_DIR}/bin:${PATH}" \ +GITHUB_ACTOR="ci-user" \ +GITHUB_TOKEN="token" \ +GITHUB_REPOSITORY="owner/repo" \ +GITHUB_WORKSPACE="${TMP_DIR}" \ +GITHUB_OUTPUT="${TMP_DIR}/output.txt" \ +INPUT_GITHUB_TOKEN="token" \ +INPUT_REPOSITORY_PATH="repo" \ +INPUT_SOURCE_BRANCH="develop" \ +INPUT_TARGET_BRANCH="main" \ +INPUT_TITLE="" \ +INPUT_TEMPLATE="${TMP_DIR}/template.md" \ +INPUT_BODY="" \ +INPUT_REVIEWER="" \ +INPUT_ASSIGNEE="" \ +INPUT_LABEL="" \ +INPUT_MILESTONE="" \ +INPUT_DRAFT="false" \ +INPUT_GET_DIFF="false" \ +INPUT_OLD_STRING="" \ +INPUT_NEW_STRING="" \ +INPUT_IGNORE_USERS="dependabot" \ +INPUT_ALLOW_NO_DIFF="false" \ +INPUT_MAX_BODY_BYTES="65000" \ +INPUT_MAX_DIFF_LINES="0" \ +bash "${SCRIPT_PATH}" >"${LOG_FILE}" 2>&1 +STATUS="$?" +set -e + +if [[ "${STATUS}" != "0" ]]; then + echo "Expected successful execution in update mode" >&2 + cat "${LOG_FILE}" >&2 + exit 1 +fi + +assert_contains "${LOG_FILE}" "Updating pull request" +assert_contains "${TMP_DIR}/output.txt" "url=https://example.test/pr/123" +assert_contains "${TMP_DIR}/output.txt" "pr_number=123" + +echo "Existing PR lookup test passed." diff --git a/tests/unit/test_template_source_selection.sh b/tests/unit/test_template_source_selection.sh index 1b91628..1841d98 100755 --- a/tests/unit/test_template_source_selection.sh +++ b/tests/unit/test_template_source_selection.sh @@ -98,13 +98,12 @@ cat > "${TMP_DIR}/bin/gh" <<'EOF' #!/usr/bin/env bash set -Eeuo pipefail -if [[ "$#" -ge 2 && "$1" == "pr" && "$2" == "list" ]]; then - echo "123" - exit 0 -fi - if [[ "$#" -ge 1 && "$1" == "api" ]]; then cmd="$*" + if [[ "${cmd}" == *"repos/owner/repo/pulls?state=open&base=release/MAPL-v3"* ]]; then + printf '%s\n' '[{"number":123,"head":{"ref":"develop","repo":{"full_name":"owner/repo"}}}]' + exit 0 + fi if [[ "${cmd}" == *"repos/owner/repo/issues/123/comments"* ]]; then echo "[]" exit 0