Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions .github/workflows/copyright-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
path: target-repo
persist-credentials: false

- name: Checkout pr-workflows repo
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/pr-workflows
ref: main
path: pr-workflows
persist-credentials: false

- name: Setup config
id: setup-config
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
cfg="target-repo/.copyrightconfig"
if [ ! -f "$cfg" ]; then
git clone --depth 1 --branch ${{ github.event.pull_request.base.ref }} \
https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git base-repo
git clone --depth 1 --branch "$BASE_REF" \
https://x-access-token:${GH_TOKEN}@github.com/${GH_REPO}.git base-repo
[ -f base-repo/.copyrightconfig ] && cfg="base-repo/.copyrightconfig"
fi
[ -f "$cfg" ] || { echo "missing config"; exit 1; }
Expand All @@ -47,12 +53,14 @@ jobs:

- name: Get changed files
id: changed-files
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
cd target-repo
base_sha="${{ github.event.pull_request.base.sha }}"
head_sha="${{ github.event.pull_request.head.sha }}"
git fetch origin ${{ github.event.pull_request.base.ref }}
git diff --name-only --diff-filter=AMR "$base_sha" "$head_sha" | while read f; do [ -f "$f" ] && echo "$f"; done > ../files_to_check.txt
git fetch origin "$BASE_REF"
git diff --name-only --diff-filter=AMR "$BASE_SHA" "$HEAD_SHA" | while read f; do [ -f "$f" ] && echo "$f"; done > ../files_to_check.txt
count=$(wc -l < ../files_to_check.txt | tr -d ' ')
if [ "$count" -eq 0 ]; then echo "skip-validation=true" >> $GITHUB_OUTPUT; else echo "skip-validation=false" >> $GITHUB_OUTPUT; fi
echo "files-count=$count" >> $GITHUB_OUTPUT
Expand All @@ -63,9 +71,10 @@ jobs:
continue-on-error: true
env:
COPYRIGHT_CHECK_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
CONFIG_FILE: ${{ steps.setup-config.outputs.config-file }}
run: |
script="pr-workflows/scripts/copyrightcheck.py"
cfg="${{ steps.setup-config.outputs.config-file }}"
cfg="$CONFIG_FILE"
[ -f "$script" ] || { echo "script missing"; exit 1; }
chmod +x "$script"
files=$(tr '\n' ' ' < files_to_check.txt)
Expand Down Expand Up @@ -123,8 +132,9 @@ jobs:
if: always() && steps.changed-files.outputs.skip-validation != 'true'
env:
COMMENT_ACTION: ${{ steps.pr-comment.outputs.comment_action }}
VALIDATION_STATUS: ${{ steps.validate.outputs.status }}
run: |
if [ "${{ steps.validate.outputs.status }}" != "success" ]; then
if [ "$VALIDATION_STATUS" != "success" ]; then
if [ "$COMMENT_ACTION" = "updated" ] || [ "$COMMENT_ACTION" = "created" ]; then
echo "::error title=Copyright Validation Failed::See the $COMMENT_ACTION PR comment for detailed results.";
else
Expand All @@ -135,4 +145,4 @@ jobs:

- name: No-op summary
if: steps.changed-files.outputs.skip-validation == 'true'
run: echo "::notice title=Copyright Check::No files to validate"
run: echo "::notice title=Copyright Check::No files to validate"
63 changes: 27 additions & 36 deletions .github/workflows/jira-id-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ on:
required: false
type: string
description: 'The PR title to check (for pull_request_target support)'
regex-pattern:
required: false
type: string
description: 'Custom regex pattern to match JIRA IDs (defaults to "[A-Z]+-[0-9]+")'
default: '[A-Z]+-[0-9]+'
fail-if-no-jira-id:
required: false
type: string
description: 'Whether to fail the check if no JIRA ID is found'
default: 'true'
allow-wip:
required: false
type: string
Expand All @@ -40,68 +30,69 @@ on:
jobs:
check-jira-id:
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- name: 🏷️ Validate JIRA ticket ID in PR title
shell: bash
env:
GH_TOKEN: ${{ github.token }}
INPUT_PR_TITLE: ${{ inputs.pr-title }}
EVENT_PR_TITLE: ${{ github.event.pull_request.title }}
PR_NUMBER: ${{ github.event.pull_request.number }}
GH_REPO: ${{ github.repository }}
INPUT_ALLOW_WIP: ${{ inputs.allow-wip }}
INPUT_CASE_SENSITIVE: ${{ inputs.case-sensitive }}
run: |
# Get PR title from context or input parameter (for pull_request_target support)
if [[ -n "${{ inputs.pr-title }}" ]]; then
PR_TITLE="${{ inputs.pr-title }}"
if [[ -n "$INPUT_PR_TITLE" ]]; then
PR_TITLE="$INPUT_PR_TITLE"
echo "Using PR title from input parameter"
else
PR_TITLE="${{ github.event.pull_request.title }}"
PR_TITLE="$EVENT_PR_TITLE"
echo "Using PR title from GitHub event context"
fi

# Fetch the current PR title from the API to handle re-runs correctly.
# When a workflow is re-run (either directly or via a reusable workflow caller),
# the event payload contains the title from the original trigger, not the current
# state. If the user edited the title (e.g., to add a JIRA ID), we need to detect
# that and use the updated title instead.
PR_NUMBER="${{ github.event.pull_request.number }}"
if [[ -n "$PR_NUMBER" ]]; then
LIVE_TITLE=$(gh pr view "$PR_NUMBER" \
--repo "${{ github.repository }}" \
--repo "$GH_REPO" \
--json title --jq '.title' 2>/dev/null || true)

if [[ -n "$LIVE_TITLE" && "$LIVE_TITLE" != "$PR_TITLE" ]]; then
echo "⚠️ PR title was updated since workflow was triggered"
echo " Event title: $PR_TITLE"
echo " Current title: $LIVE_TITLE"
echo "PR title was updated since workflow was triggered"
echo " Event title: $PR_TITLE"
echo " Current title: $LIVE_TITLE"
PR_TITLE="$LIVE_TITLE"
fi
fi
echo "PR Title: $PR_TITLE"

# Set up inputs as environment variables
# JIRA project keys are defined at the organization level
JIRA_PROJECT_KEYS="${{ env.ORGANIZATION_JIRA_PROJECT_KEYS }}"
REGEX_PATTERN="${{ inputs.regex-pattern }}"
FAIL_IF_NO_JIRA_ID="${{ inputs.fail-if-no-jira-id }}"
ALLOW_WIP="${{ inputs.allow-wip }}"
CASE_SENSITIVE="${{ inputs.case-sensitive }}"


JIRA_PROJECT_KEYS="$ORGANIZATION_JIRA_PROJECT_KEYS"
ALLOW_WIP="$INPUT_ALLOW_WIP"
CASE_SENSITIVE="$INPUT_CASE_SENSITIVE"
Comment thread
GAdityaVarma marked this conversation as resolved.

echo "Using organization-wide JIRA project keys: $JIRA_PROJECT_KEYS"
echo "Using regex pattern: $REGEX_PATTERN"
echo "Fail if no JIRA ID: $FAIL_IF_NO_JIRA_ID"
echo "Allow WIP PRs: $ALLOW_WIP"
echo "Case sensitive: $CASE_SENSITIVE"

# Handle WIP PRs
if [[ "$ALLOW_WIP" == "true" && "${PR_TITLE,,}" =~ ^wip: ]]; then
echo "This is a WIP PR. Skipping JIRA ID check."
exit 0
fi

# Convert comma-separated project keys to array
IFS=',' read -ra PROJECT_KEYS <<< "$JIRA_PROJECT_KEYS"
echo "Valid project keys: ${PROJECT_KEYS[*]}"

# Directly check for valid JIRA IDs in the PR title
VALID_ID_FOUND=false

for VALID_KEY in "${PROJECT_KEYS[@]}"; do
# Create a pattern specifically for this project key
if [[ "$CASE_SENSITIVE" == "true" ]]; then
Expand All @@ -122,7 +113,7 @@ jobs:
fi
fi
done

if [[ "$VALID_ID_FOUND" != "true" ]]; then
echo "ERROR: No JIRA ID found in PR title: \"$PR_TITLE\". Valid project keys are: $JIRA_PROJECT_KEYS"
echo "::error::No JIRA ID found in PR title: \"$PR_TITLE\". Valid project keys are: $JIRA_PROJECT_KEYS"
Expand Down
22 changes: 15 additions & 7 deletions .github/workflows/trufflehog-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Fetch PR head commits
if: github.event_name != 'workflow_dispatch'
Expand All @@ -50,6 +51,8 @@ jobs:

- name: Setup exclude config
id: config
env:
TRUFFLEHOG_EXCLUDES: ${{ vars.TRUFFLEHOG_EXCLUDES }}
run: |
# Always include default exclusions
echo "Adding default exclusions"
Expand All @@ -58,10 +61,10 @@ jobs:
EOF

# Append repo/org-level custom exclusions if defined
if [ -n "${{ vars.TRUFFLEHOG_EXCLUDES }}" ]; then
if [ -n "$TRUFFLEHOG_EXCLUDES" ]; then
echo "Adding repo/org-level TRUFFLEHOG_EXCLUDES patterns"
# Support both comma-separated and newline-separated patterns
echo "${{ vars.TRUFFLEHOG_EXCLUDES }}" | tr ',' '\n' | sed '/^$/d' >> .trufflehog-ignore
echo "$TRUFFLEHOG_EXCLUDES" | tr ',' '\n' | sed '/^$/d' >> .trufflehog-ignore
fi

echo "Exclusion patterns:"
Expand All @@ -70,7 +73,8 @@ jobs:

- name: TruffleHog Scan
id: trufflehog
uses: trufflesecurity/trufflehog@main
# Pinned to v3.94.2 commit SHA to prevent supply chain attacks via mutable tag
uses: trufflesecurity/trufflehog@6bd2d14f7a4bc1e569fa3550efa7ec632a4fa67b # v3.94.2
continue-on-error: true
with:
base: ${{ github.event.pull_request.base.sha }}
Expand Down Expand Up @@ -107,8 +111,9 @@ jobs:
echo "$CHANGED_FILES"

# Scan only the changed files in their current state using filesystem scanner
# Pinned to v3.94.2 to match the action version above
SCAN_OUTPUT=$(docker run --rm -v "$(pwd)":/tmp -w /tmp \
ghcr.io/trufflesecurity/trufflehog:latest \
ghcr.io/trufflesecurity/trufflehog:3.94.2 \
filesystem /tmp/ \
--json \
${{ steps.config.outputs.exclude_args }} \
Expand Down Expand Up @@ -154,9 +159,12 @@ jobs:
- name: Process scan results
id: process
if: github.event_name != 'workflow_dispatch'
env:
VERIFIED_COUNT: ${{ steps.parse.outputs.verified_count }}
UNVERIFIED_COUNT: ${{ steps.parse.outputs.unverified_count }}
run: |
VERIFIED=${{ steps.parse.outputs.verified_count || 0 }}
UNVERIFIED=${{ steps.parse.outputs.unverified_count || 0 }}
VERIFIED=${VERIFIED_COUNT:-0}
UNVERIFIED=${UNVERIFIED_COUNT:-0}

if [ "$VERIFIED" -gt 0 ]; then
# Verified secrets found - must fail
Expand Down Expand Up @@ -266,7 +274,7 @@ jobs:

### Understanding Results
| Type | Meaning | Action Required |
|------|---------|-----------------|
|------|---------|--------------------|
| **Verified** | Confirmed active credential | **Must remove & rotate** - PR blocked |
| **Unverified** | Potential secret pattern | Review recommended - PR can proceed |

Expand Down
Loading