167 lines
5.0 KiB
YAML
167 lines
5.0 KiB
YAML
name: "Create Gitea Pull Request"
|
|
description: "Creates a pull request on a Gitea repository via the REST API"
|
|
|
|
inputs:
|
|
gitea_url:
|
|
description: "Base URL of the Gitea instance"
|
|
required: false
|
|
default: ""
|
|
repository:
|
|
description: "Target repository as owner/repo"
|
|
required: false
|
|
default: ""
|
|
token:
|
|
description: "Gitea token with pull-request write access"
|
|
required: true
|
|
title:
|
|
description: "Pull request title"
|
|
required: true
|
|
body:
|
|
description: "Pull request description"
|
|
required: false
|
|
default: ""
|
|
head:
|
|
description: "Source branch. Same-repo: branch name. Fork: owner:branch"
|
|
required: true
|
|
base:
|
|
description: "Target branch"
|
|
required: false
|
|
default: "main"
|
|
allow_existing:
|
|
description: "If a matching open PR already exists, succeed and return it instead of failing"
|
|
required: false
|
|
default: "true"
|
|
|
|
outputs:
|
|
number:
|
|
description: "Pull request number"
|
|
value: ${{ steps.create_pr.outputs.number }}
|
|
url:
|
|
description: "API URL of the pull request"
|
|
value: ${{ steps.create_pr.outputs.url }}
|
|
html_url:
|
|
description: "Web URL of the pull request"
|
|
value: ${{ steps.create_pr.outputs.html_url }}
|
|
|
|
runs:
|
|
using: "composite"
|
|
steps:
|
|
- id: create_pr
|
|
name: Create Pull Request
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
GITEA_URL="${{ inputs.gitea_url }}"
|
|
GITEA_URL="${GITEA_URL:-${{ github.server_url }}}"
|
|
|
|
REPOSITORY="${{ inputs.repository }}"
|
|
REPOSITORY="${REPOSITORY:-${{ github.repository }}}"
|
|
|
|
TOKEN="${{ inputs.token }}"
|
|
TITLE="${{ inputs.title }}"
|
|
BODY="${{ inputs.body }}"
|
|
HEAD="${{ inputs.head }}"
|
|
BASE="${{ inputs.base }}"
|
|
BASE="${BASE:-main}"
|
|
ALLOW_EXISTING="${{ inputs.allow_existing }}"
|
|
ALLOW_EXISTING="${ALLOW_EXISTING:-true}"
|
|
|
|
if [[ ! "${REPOSITORY}" =~ ^[^/]+/[^/]+$ ]]; then
|
|
echo "::error::repository must be owner/repo, got: ${REPOSITORY}"
|
|
exit 1
|
|
fi
|
|
|
|
|
|
API_BASE="${GITEA_URL}/api/v1/repos/${REPOSITORY}"
|
|
AUTH_HEADER="Authorization: token ${TOKEN}"
|
|
|
|
echo "::notice::Creating pull request ${REPOSITORY}: ${HEAD} -> ${BASE}"
|
|
|
|
PAYLOAD="$(
|
|
jq -n \
|
|
--arg title "${TITLE}" \
|
|
--arg body "${BODY}" \
|
|
--arg head "${HEAD}" \
|
|
--arg base "${BASE}" \
|
|
'{title: $title, body: $body, head: $head, base: $base}'
|
|
)"
|
|
|
|
HTTP_CODE="$(
|
|
curl \
|
|
--silent \
|
|
--show-error \
|
|
--output /tmp/gitea-pr-response \
|
|
--write-out "%{http_code}" \
|
|
-X POST \
|
|
-H "${AUTH_HEADER}" \
|
|
-H "Content-Type: application/json" \
|
|
--data "${PAYLOAD}" \
|
|
"${API_BASE}/pulls"
|
|
)"
|
|
|
|
echo "::group::Gitea pull request API response"
|
|
echo "HTTP ${HTTP_CODE}"
|
|
cat /tmp/gitea-pr-response
|
|
echo
|
|
echo "::endgroup::"
|
|
|
|
write_outputs() {
|
|
local response_file="$1"
|
|
local number url html_url
|
|
number="$(jq -r '.number // empty' "${response_file}")"
|
|
url="$(jq -r '.url // empty' "${response_file}")"
|
|
html_url="$(jq -r '.html_url // empty' "${response_file}")"
|
|
|
|
if [ -z "${number}" ]; then
|
|
echo "::error::Could not parse pull request number from API response"
|
|
exit 1
|
|
fi
|
|
|
|
echo "number=${number}" >> "${GITHUB_OUTPUT}"
|
|
echo "url=${url}" >> "${GITHUB_OUTPUT}"
|
|
echo "html_url=${html_url}" >> "${GITHUB_OUTPUT}"
|
|
echo "::notice::Pull request #${number}: ${html_url}"
|
|
}
|
|
|
|
case "${HTTP_CODE}" in
|
|
201)
|
|
write_outputs /tmp/gitea-pr-response
|
|
;;
|
|
*)
|
|
if [ "${ALLOW_EXISTING}" = "true" ]; then
|
|
echo "::notice::Create failed with HTTP ${HTTP_CODE}. Checking for an existing open pull request."
|
|
|
|
EXISTING_CODE="$(
|
|
curl \
|
|
--silent \
|
|
--show-error \
|
|
--output /tmp/gitea-pr-existing \
|
|
--write-out "%{http_code}" \
|
|
-H "${AUTH_HEADER}" \
|
|
"${API_BASE}/pulls?state=open&head=${HEAD}"
|
|
)"
|
|
|
|
if [ "${EXISTING_CODE}" -eq 200 ]; then
|
|
MATCH="$(
|
|
jq \
|
|
--arg head "${HEAD}" \
|
|
--arg base "${BASE}" \
|
|
'[.[] | select((.head.ref == $head or .head.label == $head) and .base.ref == $base)] | .[0] // empty' \
|
|
/tmp/gitea-pr-existing
|
|
)"
|
|
|
|
if [ -n "${MATCH}" ]; then
|
|
echo "${MATCH}" > /tmp/gitea-pr-response
|
|
echo "::notice::Open pull request already exists. Reusing it."
|
|
write_outputs /tmp/gitea-pr-response
|
|
exit 0
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo "::error::Failed to create pull request with HTTP ${HTTP_CODE}"
|
|
exit 1
|
|
;;
|
|
esac
|