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
89 changes: 89 additions & 0 deletions .github/workflows/auto-pr-number.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Auto Add PR Number

on:
pull_request:
types: [opened, synchronize]

jobs:
update-commits:
name: Add PR Number to Commits
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false

permissions:
contents: write
pull-requests: write

steps:
- name: Checkout PR
uses: actions/checkout@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
ref: ${{ github.event.pull_request.head.ref }}

- name: Configure Git
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'

- name: Check and update commit messages
id: update-commits
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"
BASE_BRANCH="origin/${{ github.base_ref }}"
HEAD_BRANCH="${{ github.event.pull_request.head.ref }}"

echo "Checking commits in PR #${PR_NUMBER}"

# Get list of commits in this PR
COMMITS=$(git rev-list ${BASE_BRANCH}..HEAD)
NEEDS_UPDATE=false

for commit in $COMMITS; do
MESSAGE=$(git log -1 --pretty=%s $commit)
# Check if commit message already has a PR number
if ! echo "$MESSAGE" | grep -q "(#[0-9]\+)$"; then
echo "Commit $commit needs PR number: $MESSAGE"
NEEDS_UPDATE=true
fi
done

if [ "$NEEDS_UPDATE" = true ]; then
echo "needs_update=true" >> $GITHUB_OUTPUT

# Create a new branch for the updated commits
git checkout -b temp-pr-${PR_NUMBER}

# Rebase and add PR numbers
export PR_NUMBER
git rebase ${BASE_BRANCH} -x 'git commit --amend -m "$(git log -1 --pretty=%s) (#$PR_NUMBER)"'

# Force push the updated branch
git push --force-with-lease origin HEAD:${HEAD_BRANCH}

echo "✅ Updated commit messages with PR #${PR_NUMBER}"
else
echo "needs_update=false" >> $GITHUB_OUTPUT
echo "All commits already have PR numbers"
fi

- name: Comment on PR
if: steps.update-commits.outputs.needs_update == 'true'
uses: actions/github-script@v6
with:
script: |
const prNumber = context.payload.pull_request.number;

const comment = `## ✅ PR Number Added to Commits

I've automatically added \`(#${prNumber})\` to all commit messages in this PR.

This ensures that when using "Rebase and merge", all commits will be properly tagged with the PR number in the main branch history.`;

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: comment
});
13 changes: 13 additions & 0 deletions .github/workflows/badge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Build Status

on:
push:
branches: [ main, master ]
workflow_dispatch:

jobs:
update-badge:
runs-on: ubuntu-latest
steps:
- name: Update README badge
run: echo "Badge will be automatically available at https://github.com/${{ github.repository }}/actions/workflows/ci.yml/badge.svg"
75 changes: 75 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: CI

on:
push:
branches: [ main, master, develop, 'br_dev_*' ]
pull_request:
branches: [ main, master, develop ]

jobs:
format-check:
name: Format Check
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install -y clang-format-14

- name: Check formatting
run: |
echo "Checking code formatting..."
make check-format || {
echo "::error::Code formatting check failed"
echo "Please run 'make format' locally and commit the changes"
exit 1
}

build-and-test:
name: Build and Test
runs-on: ${{ matrix.os }}
needs: format-check

strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
build_type: [Debug, Release]

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Install dependencies (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y cmake g++ clang

- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew update
brew install cmake

- name: Configure CMake
run: |
cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}

- name: Build
run: |
cmake --build build --config ${{ matrix.build_type }} -j$(nproc 2>/dev/null || sysctl -n hw.ncpu)

- name: Test
run: |
cd build
ctest -C ${{ matrix.build_type }} --output-on-failure --verbose

- name: List all tests
if: always()
run: |
make test-list || true
43 changes: 43 additions & 0 deletions .github/workflows/clang-format-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Clang Format Check

on:
push:
branches: [ main, master, develop ]
pull_request:
branches: [ main, master, develop ]

jobs:
formatting-check:
name: Check Code Formatting
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install -y clang-format-14

- name: Check formatting
run: |
echo "Checking code formatting with clang-format..."
# Find all C++ source files
find include tests -name "*.h" -o -name "*.cpp" | while read file; do
# Format the file and check if it differs from the original
clang-format-14 --style=file "$file" | diff -u "$file" - || {
echo "::error file=$file::File is not properly formatted"
exit 1
}
done
echo "All files are properly formatted!"

- name: Suggest formatting fix
if: failure()
run: |
echo "::warning::Code formatting issues detected. Please run 'make format' locally and commit the changes."
echo "To fix formatting issues, run:"
echo " make format"
echo "or"
echo " find include tests -name '*.h' -o -name '*.cpp' | xargs clang-format -i"
140 changes: 140 additions & 0 deletions .github/workflows/enforce-pr-number.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: Enforce PR Number in Commits

# This workflow only checks NEW commits that are part of the PR
# It does not check historical commits that might already be in the base branch
on:
pull_request:
types: [opened, edited, synchronize]

jobs:
check-commit-format:
name: Check Commit Messages
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
checks: write
issues: write

steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Check commit messages
uses: actions/github-script@v6
with:
script: |
const prNumber = context.payload.pull_request.number;
const baseBranch = context.payload.pull_request.base.ref;

// Get commits in this PR - this API only returns commits unique to the PR
let commits;
try {
commits = await github.rest.pulls.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
} catch (error) {
console.log('::error::Failed to fetch PR commits. Falling back to simple check.');
console.log('Error:', error.message);
// Exit gracefully if we can't access commits
return;
}

let hasIssues = false;
const problematicCommits = [];

for (const commit of commits.data) {
const message = commit.commit.message;
const firstLine = message.split('\n')[0];

// Check if commit message has a PR number
if (!firstLine.match(/\(#\d+\)$/)) {
hasIssues = true;
problematicCommits.push({
sha: commit.sha.substring(0, 7),
message: firstLine
});
}
}

if (hasIssues) {
let comment = `## ⚠️ Commit Message Format\n\n`;
comment += `To maintain a clean git history, please add PR numbers to your commit messages.\n\n`;
comment += `### Commits missing PR number:\n\n`;

for (const commit of problematicCommits) {
comment += `- \`${commit.sha}\`: ${commit.message}\n`;
comment += ` - Suggested: \`${commit.message} (#${prNumber})\`\n`;
}

comment += `\n### How to fix:\n\n`;
comment += `\`\`\`bash\n`;
comment += `# Interactive rebase to edit commit messages\n`;
comment += `git rebase -i origin/${baseBranch}\n`;
comment += `# Mark commits as 'reword' and add (#${prNumber}) to each message\n`;
comment += `# Then force push\n`;
comment += `git push --force-with-lease\n`;
comment += `\`\`\`\n\n`;
comment += `Or use this automated approach:\n`;
comment += `\`\`\`bash\n`;
comment += `# Add PR number to all commits since base branch\n`;
comment += `git rebase origin/${baseBranch} --exec 'git commit --amend -m "$(git log -1 --pretty=%s) (#${prNumber})"'\n`;
comment += `git push --force-with-lease\n`;
comment += `\`\`\``;

// Create a check run
await github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'Commit Message Format',
head_sha: context.payload.pull_request.head.sha,
status: 'completed',
conclusion: 'neutral',
output: {
title: 'Commit messages should include PR number',
summary: comment
}
});

// Try to add label, but don't fail if we can't
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: ['needs-pr-number']
});
} catch (e) {
console.log('::warning::Could not add label (insufficient permissions)');
}
} else {
// Remove label if it exists
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
name: 'needs-pr-number'
});
} catch (e) {
// Label might not exist, that's ok
}

// Create success check
await github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'Commit Message Format',
head_sha: context.payload.pull_request.head.sha,
status: 'completed',
conclusion: 'success',
output: {
title: 'All commit messages properly formatted',
summary: 'All commits include PR numbers. Ready for rebase and merge!'
}
});
}
Loading