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
564 changes: 0 additions & 564 deletions .github/workflows/beta-release.yaml

This file was deleted.

246 changes: 4 additions & 242 deletions .github/workflows/branch-protection.yml
Original file line number Diff line number Diff line change
@@ -1,247 +1,9 @@
name: Branch Protection Check
name: Branch Protection

on:
pull_request:
branches:
- main
- master
- development
- dev
branches: [main, beta]

jobs:
quality-gate:
name: Quality Gate Check
runs-on: ubuntu-latest

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

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: mbstring, xml, ctype, iconv, intl, pdo, pdo_mysql, dom, filter, gd, json, posix, simplexml, xmlreader, xmlwriter, zip
coverage: xdebug
tools: composer:v2

- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-interaction

- name: Initialize Quality Gate Results
run: |
echo "QUALITY_GATE_PASSED=true" >> $GITHUB_ENV
echo "## 🚦 Quality Gate Status" >> $GITHUB_STEP_SUMMARY

- name: Check 1 - PHP Syntax
id: syntax
run: |
echo "### ✅ Check 1: PHP Syntax" >> $GITHUB_STEP_SUMMARY
if composer lint; then
echo "✅ No syntax errors found" >> $GITHUB_STEP_SUMMARY
echo "status=pass" >> $GITHUB_OUTPUT
else
echo "❌ FAILED: Syntax errors detected" >> $GITHUB_STEP_SUMMARY
echo "status=fail" >> $GITHUB_OUTPUT
echo "QUALITY_GATE_PASSED=false" >> $GITHUB_ENV
fi

- name: Check 2 - Coding Standards (PHPCS)
id: phpcs
run: |
echo "### Check 2: Coding Standards (PHPCS)" >> $GITHUB_STEP_SUMMARY
composer cs:check
composer phpcs:output
if [ -f phpcs-output.json ]; then
ERRORS=$(jq '.totals.errors' phpcs-output.json)
echo "errors=$ERRORS" >> $GITHUB_OUTPUT
if [ "$ERRORS" -eq "0" ]; then
echo "✅ PASSED: No PHPCS errors" >> $GITHUB_STEP_SUMMARY
echo "status=pass" >> $GITHUB_OUTPUT
else
echo "❌ FAILED: Found $ERRORS PHPCS errors (must be 0)" >> $GITHUB_STEP_SUMMARY
echo "status=fail" >> $GITHUB_OUTPUT
echo "QUALITY_GATE_PASSED=false" >> $GITHUB_ENV
fi
fi
continue-on-error: true

- name: Check 3 - Code Quality (PHPMD)
id: phpmd
run: |
echo "### Check 3: Code Quality (PHPMD)" >> $GITHUB_STEP_SUMMARY
composer phpmd > phpmd-output.txt || true
VIOLATIONS=$(cat phpmd-output.txt | wc -l)
echo "violations=$VIOLATIONS" >> $GITHUB_OUTPUT

# Allow up to 50 minor violations, fail if more
if [ "$VIOLATIONS" -le "50" ]; then
echo "✅ PASSED: $VIOLATIONS PHPMD violations (acceptable)" >> $GITHUB_STEP_SUMMARY
echo "status=pass" >> $GITHUB_OUTPUT
else
echo "❌ FAILED: $VIOLATIONS PHPMD violations (max 50)" >> $GITHUB_STEP_SUMMARY
echo "status=fail" >> $GITHUB_OUTPUT
echo "QUALITY_GATE_PASSED=false" >> $GITHUB_ENV
fi
continue-on-error: true

- name: Check 4 - Overall Quality Score
id: quality
run: |
echo "### Check 4: Overall Quality Score" >> $GITHUB_STEP_SUMMARY
composer phpqa:ci || true

if [ -f phpqa/phpqa.json ]; then
# Calculate composite quality score
PHPCS_ERRORS="${{ steps.phpcs.outputs.errors }}"
PHPMD_VIOLATIONS="${{ steps.phpmd.outputs.violations }}"

# Score calculation: Start at 100, deduct points for issues
SCORE=$(echo "scale=2; 100 - ($PHPCS_ERRORS * 2) - ($PHPMD_VIOLATIONS * 0.1)" | bc)

# Ensure score doesn't go negative
if (( $(echo "$SCORE < 0" | bc -l) )); then
SCORE=0
fi

echo "score=$SCORE" >> $GITHUB_OUTPUT
echo "Overall Quality Score: **$SCORE%**" >> $GITHUB_STEP_SUMMARY

if (( $(echo "$SCORE >= 90" | bc -l) )); then
echo "✅ PASSED: Quality score meets 90% threshold" >> $GITHUB_STEP_SUMMARY
echo "status=pass" >> $GITHUB_OUTPUT
else
echo "❌ FAILED: Quality score ($SCORE%) below 90% threshold" >> $GITHUB_STEP_SUMMARY
echo "status=fail" >> $GITHUB_OUTPUT
echo "QUALITY_GATE_PASSED=false" >> $GITHUB_ENV
fi
else
echo "⚠️ WARNING: Could not calculate quality score" >> $GITHUB_STEP_SUMMARY
echo "status=unknown" >> $GITHUB_OUTPUT
fi
continue-on-error: true

- name: Check 5 - Unit Tests
id: tests
run: |
echo "### Check 5: Unit Tests" >> $GITHUB_STEP_SUMMARY
if composer test:unit; then
echo "✅ PASSED: All unit tests pass" >> $GITHUB_STEP_SUMMARY
echo "status=pass" >> $GITHUB_OUTPUT
else
echo "⚠️ WARNING: Tests require Nextcloud environment" >> $GITHUB_STEP_SUMMARY
echo "status=skipped" >> $GITHUB_OUTPUT
fi
continue-on-error: true

- name: Final Quality Gate Decision
run: |
echo "## 🏁 Final Result" >> $GITHUB_STEP_SUMMARY

if [ "$QUALITY_GATE_PASSED" = "true" ]; then
echo "### ✅ QUALITY GATE PASSED" >> $GITHUB_STEP_SUMMARY
echo "This PR meets all quality requirements and can be merged." >> $GITHUB_STEP_SUMMARY
exit 0
else
echo "### ❌ QUALITY GATE FAILED" >> $GITHUB_STEP_SUMMARY
echo "This PR does not meet quality requirements." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Required actions:**" >> $GITHUB_STEP_SUMMARY

if [ "${{ steps.syntax.outputs.status }}" = "fail" ]; then
echo "- Fix PHP syntax errors" >> $GITHUB_STEP_SUMMARY
fi

if [ "${{ steps.phpcs.outputs.status }}" = "fail" ]; then
echo "- Fix PHPCS errors (run 'composer cs:fix')" >> $GITHUB_STEP_SUMMARY
fi

if [ "${{ steps.phpmd.outputs.status }}" = "fail" ]; then
echo "- Refactor code to reduce PHPMD violations" >> $GITHUB_STEP_SUMMARY
fi

if [ "${{ steps.quality.outputs.status }}" = "fail" ]; then
echo "- Improve overall code quality to reach 90% score" >> $GITHUB_STEP_SUMMARY
fi

echo "" >> $GITHUB_STEP_SUMMARY
echo "**Hint:** Run 'composer phpqa' locally to see detailed quality reports." >> $GITHUB_STEP_SUMMARY
exit 1
fi

- name: Upload Quality Reports
if: always()
uses: actions/upload-artifact@v3
with:
name: quality-gate-reports
path: |
phpqa/
phpcs-output.json
phpmd-output.txt
retention-days: 30

- name: Post Quality Gate Summary to PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const passed = '${{ env.QUALITY_GATE_PASSED }}' === 'true';
const syntaxStatus = '${{ steps.syntax.outputs.status }}';
const phpcsStatus = '${{ steps.phpcs.outputs.status }}';
const phpmdStatus = '${{ steps.phpmd.outputs.status }}';
const qualityStatus = '${{ steps.quality.outputs.status }}';
const testsStatus = '${{ steps.tests.outputs.status }}';

const qualityScore = '${{ steps.quality.outputs.score }}';
const phpcsErrors = '${{ steps.phpcs.outputs.errors }}';
const phpmdViolations = '${{ steps.phpmd.outputs.violations }}';

const statusEmoji = (status) => {
if (status === 'pass') return '✅';
if (status === 'fail') return '❌';
if (status === 'skipped') return '⚠️';
return '❓';
};

const body = `## 🚦 Quality Gate Status: ${passed ? '✅ PASSED' : '❌ FAILED'}

| Check | Status | Details |
|-------|--------|---------|
| PHP Syntax | ${statusEmoji(syntaxStatus)} ${syntaxStatus.toUpperCase()} | All PHP files must be valid |
| Coding Standards (PHPCS) | ${statusEmoji(phpcsStatus)} ${phpcsStatus.toUpperCase()} | Errors: ${phpcsErrors} (must be 0) |
| Code Quality (PHPMD) | ${statusEmoji(phpmdStatus)} ${phpmdStatus.toUpperCase()} | Violations: ${phpmdViolations} (max 50) |
| Overall Quality Score | ${statusEmoji(qualityStatus)} ${qualityStatus.toUpperCase()} | Score: ${qualityScore}% (min 90%) |
| Unit Tests | ${statusEmoji(testsStatus)} ${testsStatus.toUpperCase()} | Test suite status |

### Requirements for Merge

${passed ?
'✅ **All quality checks passed!** This PR meets the requirements for merging.' :
'❌ **Quality gate failed.** Please address the issues above before merging.'}

${!passed ? `
### How to Fix

1. Run \`composer cs:fix\` to auto-fix coding standards
2. Run \`composer phpqa\` to see detailed quality reports
3. Review the generated report at \`phpqa/phpqa-offline.html\`
4. Fix any critical issues and re-push your changes

📚 See [Quality Assurance Documentation](../docs/quality-assurance.md) for more details.
` : ''}

📊 Detailed reports are available in the workflow artifacts.
`;

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
continue-on-error: true



check:
uses: ConductionNL/.github/.github/workflows/branch-protection.yml@main
14 changes: 14 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Code Quality

on:
push:
branches: [main, development, feature/**, bugfix/**, hotfix/**]
pull_request:
branches: [main, beta, development]

jobs:
quality:
uses: ConductionNL/.github/.github/workflows/quality.yml@main
with:
app-name: openregister
enable-phpunit: true
89 changes: 5 additions & 84 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,91 +2,12 @@ name: Documentation

on:
push:
branches:
- development
branches: [documentation]
pull_request:
branches:
- development
branches: [documentation]

jobs:
deploy:
name: Deploy Documentation
runs-on: ubuntu-latest
# Only deploy on push, not on pull requests
if: github.event_name == 'push'
permissions:
contents: write
steps:
# https://github.com/marketplace/actions/checkout
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js 18
uses: actions/setup-node@v3
with:
node-version: '18'

- name: Copy CONTRIBUTING.md to documentation
run: |
# Copy CONTRIBUTING.md to docs/development/ with Docusaurus frontmatter
{
echo "---"
echo "sidebar_position: 1"
echo "title: Contributing"
echo "description: Guidelines for contributing to OpenRegister, including PR descriptions and changelog formatting"
echo "---"
echo ""
cat CONTRIBUTING.md
} > docs/development/contributing.md
echo "✓ Copied CONTRIBUTING.md to docs/development/contributing.md"

- name: Clear build cache and install dependencies
timeout-minutes: 3
run: |
cd docusaurus
rm -rf node_modules/.cache
rm -rf .docusaurus
rm -rf build
npm run ci

- name: Verify build output
run: |
cd docusaurus/build
if [ ! -f index.html ]; then
echo "ERROR: index.html not found in build directory!"
exit 1
fi

- name: Create .nojekyll and CNAME files
run: |
cd docusaurus/build
touch .nojekyll
echo "openregisters.app" > CNAME

# Deploy to GitHub Pages
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docusaurus/build
publish_branch: gh-pages
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
force_orphan: false
allow_empty_commit: true
keep_files: false

- name: Verify deployment
run: |
git fetch origin gh-pages
echo "✅ Deployment completed. Latest commit: $(git rev-parse origin/gh-pages)"

# https://github.com/marketplace/actions/create-an-issue
- name: Create issue on failure
if: failure()
uses: JasonEtco/create-an-issue@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
filename: .github/DOCUMENTATION_ISSUE_TEMPLATE.md
uses: ConductionNL/.github/.github/workflows/documentation.yml@main
with:
cname: openregisters.app
7 changes: 4 additions & 3 deletions .github/workflows/issues-from-markdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ name: Create Issues from Markdown
on:
push:
branches:
- main
- master
- development
# - main
# - master
# - development
- never
paths:
- 'issues/*.md'
- '!issues/README.md'
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/pr-to-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: Create or update PR to beta

on:
push:
branches: [development]

jobs:
sync:
uses: ConductionNL/.github/.github/workflows/sync-to-beta.yml@main
Loading
Loading