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: "https://gitea.psi.ch" 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 env: INPUT_GITEA_URL: ${{ inputs.gitea_url }} INPUT_REPOSITORY: ${{ inputs.repository }} INPUT_TOKEN: ${{ inputs.token }} INPUT_TITLE: ${{ inputs.title }} INPUT_BODY: ${{ inputs.body }} INPUT_HEAD: ${{ inputs.head }} INPUT_BASE: ${{ inputs.base }} INPUT_ALLOW_EXISTING: ${{ inputs.allow_existing }} GITHUB_REPOSITORY: ${{ github.repository }} run: | set -euo pipefail GITEA_URL="${INPUT_GITEA_URL:-https://gitea.psi.ch}" REPOSITORY="${INPUT_REPOSITORY:-${GITHUB_REPOSITORY}}" HEAD="${INPUT_HEAD}" BASE="${INPUT_BASE:-main}" ALLOW_EXISTING="${INPUT_ALLOW_EXISTING:-true}" if [[ ! "${REPOSITORY}" =~ ^[^/]+/[^/]+$ ]]; then echo "::error::repository must be owner/repo, got: ${REPOSITORY}" exit 1 fi if [ -z "${INPUT_TOKEN}" ]; then echo "::error::token is required" exit 1 fi if [ -z "${INPUT_TITLE}" ]; then echo "::error::title is required" exit 1 fi if [ -z "${HEAD}" ]; then echo "::error::head is required" exit 1 fi API_BASE="${GITEA_URL}/api/v1/repos/${REPOSITORY}" AUTH_HEADER="Authorization: token ${INPUT_TOKEN}" echo "::notice::Creating pull request ${REPOSITORY}: ${HEAD} -> ${BASE}" PAYLOAD="$( jq -n \ --arg title "${INPUT_TITLE}" \ --arg body "${INPUT_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