diff --git a/.github/scripts/sanitize_payload.sh b/.github/scripts/sanitize_payload.sh new file mode 100755 index 0000000000..dd4ce6315d --- /dev/null +++ b/.github/scripts/sanitize_payload.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +set -euo pipefail +IFS=$'\n\t' + +# Inputs via environment variables +RAW_DEP=${RAW_DEP:-} +RAW_SHA=${RAW_SHA:-} +RAW_USER=${RAW_USER:-} +RAW_MAIL=${RAW_MAIL:-} + +# --- Validate dependency via allow-list and map to module path + label +case "${RAW_DEP:-}" in + dolt) + MODULE='github.com/dolthub/dolt/go' + LABEL='dolt-bump' + ;; + *) + echo "Unsupported dependency '${RAW_DEP:-}'" >&2 + exit 1 + ;; +esac + +# --- Validate head SHA/tag (conservative) +# allow only hex SHAs or safe tag-ish: letters, digits, dot, dash, underscore, plus +if [ -z "${RAW_SHA:-}" ] || ! printf '%s' "$RAW_SHA" | grep -qE '^[A-Za-z0-9._+-]+$'; then + echo "Invalid head_commit_sha" >&2 + exit 1 +fi + +# Keep a short 8-char form if it's a hex SHA; otherwise derive short safe token +if printf '%s' "$RAW_SHA" | grep -qiE '^[0-9a-f]{40}$'; then + SHORT_SHA="${RAW_SHA:0:8}" +else + SHORT_SHA="$(printf '%s' "$RAW_SHA" | tr -cd 'A-Za-z0-9._+-' | cut -c1-12)" +fi + +# --- Determine candidate assignee (map bot -> zachmu), then validate +if [ "${RAW_USER:-}" = "github-actions[bot]" ]; then + USER_CAND='zachmu' +else + USER_CAND="${RAW_USER:-}" +fi + +if [ -z "${USER_CAND:-}" ] || ! printf '%s' "$USER_CAND" | grep -qE '^[A-Za-z0-9-]{1,39}$'; then + echo "Invalid assignee username" >&2 + exit 1 +fi + +# --- Validate email; if invalid, fall back to GitHub noreply +if [ -n "${RAW_MAIL:-}" ] && printf '%s' "$RAW_MAIL" | grep -qE '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'; then + SAFE_EMAIL="$RAW_MAIL" +else + SAFE_EMAIL="${USER_CAND}+noreply@users.noreply.github.com" +fi + +# --- Build a safe branch name: - +BRANCH_NAME="$(printf '%s-%s' "$USER_CAND" "$SHORT_SHA" | tr -cd 'A-Za-z0-9._-')" + +# Expose sanitized values as step outputs +{ + echo "label=$LABEL" + echo "safe_module=$MODULE" + echo "safe_head=$RAW_SHA" + echo "safe_assignee=$USER_CAND" + echo "safe_email=$SAFE_EMAIL" + echo "safe_branch=$BRANCH_NAME" + echo "safe_short=$SHORT_SHA" +} >> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/bump-dependency.yaml b/.github/workflows/bump-dependency.yaml index aac671eb6d..187bec62bd 100644 --- a/.github/workflows/bump-dependency.yaml +++ b/.github/workflows/bump-dependency.yaml @@ -5,28 +5,31 @@ on: types: [ bump-dependency ] jobs: - get-label: - name: Get Label - outputs: - label: ${{ steps.get-label.outputs.label }} + sanitize-payload: + name: Sanitize Payload runs-on: ubuntu-22.04 + outputs: + label: ${{ steps.sanitize.outputs.label }} + safe_module: ${{ steps.sanitize.outputs.safe_module }} + safe_head: ${{ steps.sanitize.outputs.safe_head }} + safe_assignee: ${{ steps.sanitize.outputs.safe_assignee }} + safe_email: ${{ steps.sanitize.outputs.safe_email }} + safe_branch: ${{ steps.sanitize.outputs.safe_branch }} + safe_short: ${{ steps.sanitize.outputs.safe_short }} steps: - - name: Get Label - id: get-label + - uses: actions/checkout@v4 + - name: Validate & Sanitize Payload (script) + id: sanitize env: - REPO: ${{ github.event.client_payload.dependency }} - run: | - if [ "$REPO" == "dolt" ] - then - echo "label=dolt-bump" >> $GITHUB_OUTPUT - else - echo "$REPO is unsupported" - exit 1 - fi + RAW_DEP: ${{ github.event.client_payload.dependency }} + RAW_SHA: ${{ github.event.client_payload.head_commit_sha }} + RAW_USER: ${{ github.event.client_payload.assignee }} + RAW_MAIL: ${{ github.event.client_payload.assignee_email }} + run: bash .github/scripts/sanitize_payload.sh stale-bump-prs: name: Retrieving Stale Bump PRs - needs: get-label + needs: sanitize-payload outputs: stale-pulls: ${{ steps.get-stale-prs.outputs.open-pulls }} runs-on: ubuntu-22.04 @@ -35,7 +38,7 @@ jobs: id: get-stale-prs uses: actions/github-script@v7 env: - LABEL: ${{ needs.get-label.outputs.label }} + LABEL: ${{ needs.sanitize-payload.outputs.label }} with: debug: true github-token: ${{ secrets.GITHUB_TOKEN }} @@ -85,7 +88,7 @@ jobs: } open-bump-pr: - needs: [get-label, stale-bump-prs] + needs: [sanitize-payload, stale-bump-prs] name: Open Bump PR runs-on: ubuntu-22.04 outputs: @@ -98,55 +101,53 @@ jobs: uses: actions/setup-go@v5 with: go-version-file: go.mod - - name: Bump dependency + - name: Bump dependency (safe) + env: + SAFE_MODULE: ${{ needs.sanitize-payload.outputs.safe_module }} + SAFE_HEAD: ${{ needs.sanitize-payload.outputs.safe_head }} run: | - go get github.com/dolthub/${{ github.event.client_payload.dependency }}/go@${{ github.event.client_payload.head_commit_sha }} + GOOS=linux go get "${SAFE_MODULE}@${SAFE_HEAD}" go mod tidy - - name: Get short hash - id: short-sha - run: | - commit=${{ github.event.client_payload.head_commit_sha }} - short=${commit:0:8} - echo "short=$short" >> $GITHUB_OUTPUT - - name: Get Assignee and Reviewer + + - name: Get Assignee and Reviewer (safe) id: get_reviewer + env: + ASSIGNEE: ${{ needs.sanitize-payload.outputs.safe_assignee }} run: | - if [ "${{ github.event.client_payload.assignee }}" == "github-actions[bot]" ] - then - echo "assignee=zachmu" >> $GITHUB_OUTPUT - else - assignee="${{ github.event.client_payload.assignee }}" - echo "assignee=$assignee" >> $GITHUB_OUTPUT - fi - - if [ "${{ github.event.client_payload.assignee }}" == "zachmu" ] + echo "assignee=${ASSIGNEE}" >> $GITHUB_OUTPUT + if [ "${ASSIGNEE}" == "zachmu" ] then echo "reviewer=Hydrocharged" >> $GITHUB_OUTPUT else echo "reviewer=zachmu" >> $GITHUB_OUTPUT fi - - name: Create and Push new branch + - name: Create and Push new branch (safe) + env: + GIT_USER: ${{ needs.sanitize-payload.outputs.safe_assignee }} + GIT_MAIL: ${{ needs.sanitize-payload.outputs.safe_email }} + BRANCH: ${{ needs.sanitize-payload.outputs.safe_branch }} + COMMIT_BY: ${{ needs.sanitize-payload.outputs.safe_assignee }} run: | - git config --global --add user.name "${{ steps.get_reviewer.outputs.assignee }}" - git config --global --add user.email "${{ github.event.client_payload.assignee_email }}" - branchname=${{ format('{0}-{1}', steps.get_reviewer.outputs.assignee, steps.short-sha.outputs.short) }} - git checkout -b "$branchname" + set -euo pipefail + git config --global user.name "${GIT_USER}" + git config --global user.email "${GIT_MAIL}" + git checkout -b "${BRANCH}" git add . - git commit -m "${{ format('[ga-bump-dep] Bump dependency in Doltgres by {0}', steps.get_reviewer.outputs.assignee) }}" - git push origin "$branchname" + git commit -m "[ga-bump-dep] Bump dependency in Doltgres by ${COMMIT_BY}" + git push origin "${BRANCH}" - name: pull-request uses: repo-sync/pull-request@v2 id: latest-pr with: - source_branch: ${{ format('{0}-{1}', steps.get_reviewer.outputs.assignee, steps.short-sha.outputs.short ) }} + source_branch: ${{ needs.sanitize-payload.outputs.safe_branch }} destination_branch: "main" github_token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN || secrets.REPO_ACCESS_TOKEN || secrets.GITHUB_TOKEN }} - pr_title: "[auto-bump] [no-release-notes] dependency by ${{ steps.get_reviewer.outputs.assignee }}" + pr_title: "[auto-bump] [no-release-notes] dependency by ${{ needs.sanitize-payload.outputs.safe_assignee }}" pr_template: ".github/markdown-templates/dep-bump.md" pr_reviewer: ${{ steps.get_reviewer.outputs.reviewer }} - pr_assignee: ${{ github.event.client_payload.assignee }} - pr_label: ${{ needs.get-label.outputs.label }} + pr_assignee: ${{ needs.sanitize-payload.outputs.safe_assignee }} + pr_label: ${{ needs.sanitize-payload.outputs.label }} comment-on-stale-prs: needs: [open-bump-pr, stale-bump-prs]