commit 20474dc7987ce57b65ee2339e3f22e837ec6829c Author: pombas_n Date: Wed Sep 30 10:54:06 2026 +0200 Add actions.yaml diff --git a/actions.yaml b/actions.yaml new file mode 100644 index 0000000..bf17484 --- /dev/null +++ b/actions.yaml @@ -0,0 +1,181 @@ +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