From 25c06a909a6e03740512d1064cdf1fbe920f6754 Mon Sep 17 00:00:00 2001 From: Marc Beinder Date: Thu, 4 Dec 2025 13:15:31 -0600 Subject: [PATCH] [Actions] Convert Format Pull Request Title Action to Docker --- .github/workflows/_release.yml | 2 + .../github/formatPullRequestTitle/Dockerfile | 41 ++++++++ .../github/formatPullRequestTitle/action.yml | 94 ++----------------- .../formatPullRequestTitle/entrypoint.sh | 73 -------------- 4 files changed, 52 insertions(+), 158 deletions(-) create mode 100644 actions/github/formatPullRequestTitle/Dockerfile delete mode 100644 actions/github/formatPullRequestTitle/entrypoint.sh diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index af0b503..c04055c 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -25,6 +25,8 @@ jobs: imageName: 'gh-action-json-diff-alert' - actionPath: 'actions/github/enrichPullRequest' imageName: 'gh-action-enrich-pull-request' + - actionPath: 'actions/github/formatPullRequestTitle' + imageName: 'gh-action-format-pull-request-title' uses: ./.github/workflows/_github_createAndReleaseActionDockerImage.yml with: actionPath: ${{ matrix.actionPath }} diff --git a/actions/github/formatPullRequestTitle/Dockerfile b/actions/github/formatPullRequestTitle/Dockerfile new file mode 100644 index 0000000..197806c --- /dev/null +++ b/actions/github/formatPullRequestTitle/Dockerfile @@ -0,0 +1,41 @@ +FROM golang:1.24-alpine AS builder + +WORKDIR /app + +# Copy go mod and sum files +COPY go.mod go.sum ./ + +# Download dependencies +RUN go mod download + +# Copy source code +COPY main.go ./ + +# Build the binary +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . + +# Final stage - minimal image +FROM alpine:latest + +# Install ca-certificates for HTTPS requests +RUN apk --no-cache add ca-certificates + +# Create a non-root user +RUN addgroup -g 1001 -S appgroup && \ + adduser -u 1001 -S appuser -G appgroup + +# Set working directory +WORKDIR /app + +# Copy the binary from builder stage +COPY --from=builder /app/main . + +# Set ownership and permissions +RUN chown appuser:appgroup /app/main && \ + chmod +x /app/main + +# Switch to non-root user +USER appuser + +# Run the binary +ENTRYPOINT ["/app/main"] \ No newline at end of file diff --git a/actions/github/formatPullRequestTitle/action.yml b/actions/github/formatPullRequestTitle/action.yml index b722b79..090c992 100644 --- a/actions/github/formatPullRequestTitle/action.yml +++ b/actions/github/formatPullRequestTitle/action.yml @@ -25,89 +25,13 @@ inputs: required: false default: false type: boolean -runs: - using: 'composite' - steps: - - uses: actions/checkout@v4 - with: - repository: ${{github.action_repository}} - - - name: Setup Go - if: ${{ inputs.useGo }} - uses: actions/setup-go@v5 - with: - go-version: '>=1.24.1' - go-version-file: '${{github.action_path}}/go.mod' - cache: true - cache-dependency-path: '${{github.action_path}}/go.sum' - - - name: Generate Main Hash - id: mainHash - shell: bash - run: echo "hash=$(sha256sum ${{github.action_path}}/main.go | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT - - - name: Generate Module Hash - id: moduleHash - shell: bash - run: echo "hash=$(sha256sum ${{github.action_path}}/go.sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT - - - name: Restore Go Modules Cache - if: ${{ inputs.useGo }} - uses: actions/cache@v4 - id: goModuleCache - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-modules-${{ steps.moduleHash.outputs.hash }} - - - name: Restore Binary Cache - if: ${{ inputs.useGo }} - uses: actions/cache@v4 - id: binary-cache - with: - path: ${{github.action_path}}/action-binary - key: ${{ runner.os }}-go-binary-${{ steps.mainHash.outputs.hash }} - - name: Tidy Go Modules - if: ${{ inputs.useGo && steps.binary-cache.outputs.cache-hit != 'true' }} - shell: bash - working-directory: ${{github.action_path}} - run: go mod tidy - - - name: Build Binary - if: ${{ inputs.useGo && steps.binary-cache.outputs.cache-hit != 'true' }} - shell: bash - working-directory: ${{github.action_path}} - run: go build -o ${{github.action_path}}/action-binary main.go - - - name: Set Execute Permissions on Binary - if: ${{ inputs.useGo && steps.binary-cache.outputs.cache-hit == 'true' }} - shell: bash - working-directory: ${{github.action_path}} - run: chmod +x ${{github.action_path}}/action-binary - - - name: "Format Pull Request Title" - if: ${{ inputs.useGo }} - shell: bash - working-directory: ${{github.action_path}} - run: ${{github.action_path}}/action-binary - env: - GH_TOKEN: ${{ inputs.token }} - GH_REPOSITORY: ${{ inputs.repository }} - PR_NUMBER: ${{ inputs.pullRequestNumber }} - BRANCH_NAME: ${{ inputs.branch }} - CI_FMT_WORDS: ${{ inputs.customFormatting }} - - - name: "Set execute permissions [NOTICE: This will be removed in the next major version]" - if: ${{ !inputs.useGo }} - shell: bash - run: chmod +x ${{github.action_path}}/entrypoint.sh - - - name: "Format Pull Request Title (Legacy) [NOTICE: This will be removed in the next major version]" - if: ${{ !inputs.useGo }} - shell: bash - run: ${{github.action_path}}/entrypoint.sh - env: - GH_TOKEN: ${{ inputs.token }} - GH_REPOSITORY: ${{ inputs.repository }} - PR_NUMBER: ${{ inputs.pullRequestNumber }} - BRANCH_NAME: ${{ inputs.branch }} +runs: + using: 'docker' + image: 'docker://ghcr.io/encoredigitalgroup/gh-action-format-pull-request-title:latest' + env: + GH_TOKEN: ${{ inputs.token }} + GH_REPOSITORY: ${{ inputs.repository }} + PR_NUMBER: ${{ inputs.pullRequestNumber }} + BRANCH_NAME: ${{ inputs.branch }} + CI_FMT_WORDS: ${{ inputs.customFormatting }} \ No newline at end of file diff --git a/actions/github/formatPullRequestTitle/entrypoint.sh b/actions/github/formatPullRequestTitle/entrypoint.sh deleted file mode 100644 index 8ba989f..0000000 --- a/actions/github/formatPullRequestTitle/entrypoint.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash - -githubToken=$GH_TOKEN -repoOwner=$(echo "$GH_REPOSITORY" | cut -d'/' -f1) -repoName=$(echo "$GH_REPOSITORY" | cut -d'/' -f2) -prNumber=$PR_NUMBER -branchName=$BRANCH_NAME -prTitle='' - -regexWithIssueType="^(epic|feature|bugfix|hotfix)/([A-Z]+-[0-9]+)-(.+)$" -regexWithoutIssueType="^([A-Z]+-[0-9]+)-(.+)$" - -formatTitle() { - local title="$1" - if [[ $title =~ $regexWithIssueType ]]; then - issueKey="${BASH_REMATCH[2]}" - issueName="${BASH_REMATCH[3]}" - elif [[ $title =~ $regexWithoutIssueType ]]; then - issueKey="${BASH_REMATCH[1]}" - issueName="${BASH_REMATCH[2]}" - else - echo "Title does not match expected format" - echo "$title" - return - fi - - formattedIssueName=$(echo "$issueName" | sed -e 's/-/ /g' -e 's/\b\w/\u&/g') - fullFormattedName="[$issueKey] $formattedIssueName" - echo "$fullFormattedName" -} - -updatePullRequestTitle() { - local title - title=$(formatTitle "$1") - echo "Attempting to Update Pull Request Title to: $title" - - curl -X PATCH \ - -H "Authorization: token $githubToken" \ - -H "Accept: application/vnd.github.v3+json" \ - -d "{\"title\":\"$title\"}" \ - "https://api.github.com/repos/$repoOwner/$repoName/pulls/$prNumber" -} - -branchNameMatches() { - local pullRequestTitle - pullRequestTitle=$(curl -s \ - -H "Authorization: token $githubToken" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/$repoOwner/$repoName/pulls/$prNumber" | jq -r '.title') - - echo "Pull Request Title is: $pullRequestTitle" - prTitle="$pullRequestTitle" - - if [[ "$prTitle" == "$(formatTitle "$branchName")" ]]; then - echo "Pull Request Titles Match" - return 0 - else - echo "Pull Request Titles Do Not Match" - return 1 - fi -} - -act() { - COL_NOTICE_YELLOW="\033[33m" - COL_RESET="\033[0m" - echo -e "${COL_NOTICE_YELLOW}NOTICE: The shell script version of this action will be removed in the next major version and will be replaced with the version written in Go. No action is required from you unless you opted into the Go preview.${COL_RESET}" - if ! branchNameMatches "$branchName"; then - echo "Pull Request Title Should Be Updated." - updatePullRequestTitle "$branchName" - fi -} - -act