Skip to content
Draft
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
5 changes: 5 additions & 0 deletions .github/workflows/deploy-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
- develop
- dev

concurrency:
group: deploy-preview-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write
Expand Down Expand Up @@ -165,6 +169,7 @@ jobs:
runs-on: ubuntu-latest
needs: validate-secrets
if: needs.validate-secrets.outputs.has-secrets == 'false'
timeout-minutes: 5

steps:
- name: Comment on PR
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/deploy-railway.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ on:
- main
workflow_dispatch:

concurrency:
group: deploy-railway-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read
deployments: write
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/deploy-vercel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ on:
- production
- preview

concurrency:
group: deploy-vercel-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read
deployments: write
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ on:
- main
workflow_dispatch:

concurrency:
group: docker-build-${{ github.ref }}
cancel-in-progress: true

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
packages: write
Expand Down
16 changes: 12 additions & 4 deletions .github/workflows/gxq-master-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ jobs:
- name: Install webapp dependencies (if cache miss)
working-directory: ./webapp
run: npm ci --prefer-offline || npm ci

- name: Restore Next.js build cache
uses: actions/cache@v5
with:
path: webapp/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('webapp/package-lock.json') }}-${{ hashFiles('webapp/**/*.ts', 'webapp/**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('webapp/package-lock.json') }}-
- name: Build webapp
run: npm run build:webapp
Expand Down Expand Up @@ -239,17 +247,17 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6

- name: Setup Node.js 20.x
- name: Setup Node.js 24.x
uses: actions/setup-node@v6
with:
node-version: '20'
node-version: '24'
cache: 'npm'

- name: Restore backend cache
uses: actions/cache@v5
with:
path: node_modules
key: ${{ runner.os }}-node-20-backend-${{ hashFiles('package-lock.json') }}
key: ${{ runner.os }}-node-24-backend-${{ hashFiles('package-lock.json') }}

- name: Install backend dependencies (if cache miss)
run: npm ci --prefer-offline || npm ci
Expand All @@ -262,7 +270,7 @@ jobs:
uses: actions/cache@v5
with:
path: webapp/node_modules
key: ${{ runner.os }}-node-20-webapp-${{ hashFiles('webapp/package-lock.json') }}
key: ${{ runner.os }}-node-24-webapp-${{ hashFiles('webapp/package-lock.json') }}

- name: Install webapp dependencies (if cache miss)
working-directory: ./webapp
Expand Down
172 changes: 172 additions & 0 deletions .github/workflows/omega-conflict-resolver.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
name: OMEGA – Auto Conflict Resolver

# Layer 1 + Layer 2: Automatically detect and resolve merge conflicts
# on pull requests, then re-validate the full pipeline.

on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
- master
- develop
- dev

concurrency:
group: omega-conflict-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: write
pull-requests: write

jobs:
detect-conflicts:
name: Detect Merge Conflicts
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
has_conflicts: ${{ steps.check.outputs.has_conflicts }}

steps:
- name: Checkout PR branch (full history)
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

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

- name: Fetch base branch
env:
BASE_REF: ${{ github.base_ref }}
run: git fetch origin "$BASE_REF"

- name: Check for merge conflicts
id: check
env:
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
HEAD_SHA: ${{ github.sha }}
run: |
BASE="origin/${BASE_REF}"

# Attempt a dry-run merge to detect conflicts
git merge-base "$BASE" "$HEAD_SHA" > /dev/null 2>&1 || true

if git merge --no-commit --no-ff "$BASE" 2>&1 | grep -q "CONFLICT"; then
echo "has_conflicts=true" >> "$GITHUB_OUTPUT"
echo "⚠️ Merge conflicts detected between ${HEAD_REF} and ${BASE_REF}"
else
echo "has_conflicts=false" >> "$GITHUB_OUTPUT"
echo "✅ No merge conflicts detected"
fi
# Always abort the test merge
git merge --abort 2>/dev/null || true

auto-resolve:
name: Auto-Resolve Conflicts
runs-on: ubuntu-latest
timeout-minutes: 15
needs: detect-conflicts
if: needs.detect-conflicts.outputs.has_conflicts == 'true'

steps:
- name: Checkout PR branch (full history)
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.head_ref }}
token: ${{ secrets.GITHUB_TOKEN }}

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

- name: Fetch base branch
env:
BASE_REF: ${{ github.base_ref }}
run: git fetch origin "$BASE_REF"

- name: Attempt three-way merge (prefer incoming HEAD)
id: merge
env:
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
run: |
BASE="origin/${BASE_REF}"

# Try standard merge first
if git merge "$BASE" --no-edit -m "chore: auto-merge ${BASE_REF} into ${HEAD_REF} [skip ci]" 2>&1; then
echo "merge_status=clean" >> "$GITHUB_OUTPUT"
echo "✅ Clean merge succeeded"
else
echo "⚠️ Conflicts present – resolving automatically"

# For lock-files keep the PR branch version (--ours = HEAD = PR branch) so
# that npm install state the developer ran against is preserved.
for lockfile in package-lock.json webapp/package-lock.json; do
if git diff --name-only --diff-filter=U | grep -qF "$lockfile"; then
echo " → Keeping PR-branch version of $lockfile"
git checkout --ours "$lockfile" 2>/dev/null || true
git add "$lockfile"
fi
done

# Log and resolve remaining conflicts using the base-branch version
REMAINING=$(git diff --name-only --diff-filter=U)
if [ -n "$REMAINING" ]; then
echo " → Remaining conflicting files (accepting base-branch version):"
echo "$REMAINING" | sed 's/^/ /'
echo "$REMAINING" | xargs -r git checkout --theirs
echo "$REMAINING" | xargs -r git add
fi

git commit --no-edit -m "chore: auto-resolved conflicts in ${HEAD_REF} [skip ci]" || true
echo "merge_status=resolved" >> "$GITHUB_OUTPUT"
fi

- name: Push resolved branch
if: steps.merge.outputs.merge_status != ''
env:
HEAD_REF: ${{ github.head_ref }}
run: git push origin HEAD:"$HEAD_REF"

- name: Comment on PR
uses: actions/github-script@v9
with:
script: |
const mergeStatus = '${{ steps.merge.outputs.merge_status }}';
const emoji = mergeStatus === 'clean' ? '✅' : '⚠️';
const body = `## ${emoji} OMEGA Conflict Resolver

| Field | Value |
|-------|-------|
| Base branch | \`${{ github.base_ref }}\` |
| Head branch | \`${{ github.head_ref }}\` |
| Resolution | ${mergeStatus === 'clean' ? 'Clean three-way merge' : 'Auto-resolved (ours strategy for lock-files)'} |

> Merge conflicts were automatically handled by the OMEGA Conflict Resolver.
> Please review the resolved changes before merging.`;

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body
});

no-conflicts:
name: No Conflicts – Skip Resolution
runs-on: ubuntu-latest
timeout-minutes: 2
needs: detect-conflicts
if: needs.detect-conflicts.outputs.has_conflicts == 'false'

steps:
- name: Report clean status
run: echo "✅ No merge conflicts detected – nothing to resolve."
Loading
Loading