Skip to content

Enforce RBAC on scan and M365 connection mutations (26T2-BE-PG-001). #33

Enforce RBAC on scan and M365 connection mutations (26T2-BE-PG-001).

Enforce RBAC on scan and M365 connection mutations (26T2-BE-PG-001). #33

name: "Backend + API CI/CD"
on:
push:
branches: [main]
paths:
- 'backend-api/**'
pull_request:
branches: [main]
paths:
- 'backend-api/**'
schedule:
- cron: '32 23 * * 6'
jobs:
analyze:
name: Security Analysis on (${{ matrix.language }})
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
security-events: write
packages: read
actions: read
contents: read
strategy:
fail-fast: false
matrix:
language: ['python']
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
- name: Install Bandit
run: pip install bandit
- name: Run Bandit scan on backend-api
# Exclude pytest suites: Bandit B101 flags assert, which is expected in tests.
run: bandit -r backend-api -x backend-api/tests -f txt
run-lint:
name: Linting Code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Lint Code Base
uses: github/super-linter@v4
env:
VALIDATE_ALL_CODEBASE: false
DEFAULT_BRANCH: "main"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_YAML: false
VALIDATE_GITHUB_ACTIONS: false
VALIDATE_PYTHON_BLACK: false
VALIDATE_PYTHON_FLAKE8: false
VALIDATE_PYTHON_ISORT: false
VALIDATE_JAVASCRIPT_STANDARD: false
VALIDATE_HTML: false
VALIDATE_MARKDOWN: false
VALIDATE_MARKDOWN_PRETTIER: false
VALIDATE_NATURAL_LANGUAGE: false
report:
name: Report PR status
needs: [analyze, run-lint]
if: always() && github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/github-script@v7
with:
script: |
const analyze = '${{ needs.analyze.result }}';
const lint = '${{ needs.run-lint.result }}';
const icon = r => ({ success: '✅', failure: '❌', cancelled: '🚫', skipped: '⏭️' }[r] ?? '❓');
const allPassed = [analyze, lint].every(r => ['success', 'skipped'].includes(r));
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const marker = '<!-- ci-report-backend-api -->'; // used to find and update the existing comment
const body = [
marker,
`### CI: Backend API`,
``,
`| Job | Result |`,
`|---|---|`,
`| Security analysis (CodeQL + Bandit) | ${icon(analyze)} \`${analyze}\` |`,
`| Lint | ${icon(lint)} \`${lint}\` |`,
``,
allPassed
? `All checks passed.`
: `One or more checks failed. [View logs](${runUrl})`,
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c => c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}