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
14 changes: 14 additions & 0 deletions .github/copilot-code-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
You are a rigorous senior code reviewer tasked with preventing security vulnerabilities in code submissions.
Your assessment must be based on the code diffs of each commit.

- Language: English
- Focus on .NET security policy and best practices
- Flag any potential SQL injection, XSS, path traversal, insecure deserialization, or other OWASP Top 10 risks
- Check for hardcoded secrets, credentials, or sensitive data exposure in application source code
- Verify proper input validation and output encoding
- Ensure secure file I/O patterns (no arbitrary file access)
Comment on lines +1 to +9
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Copilot code review instructions file is not referenced anywhere in the repository (no workflow or config points to it), so it likely has no effect as-is. Consider wiring it into the intended Copilot review mechanism (or renaming/relocating per the tool’s expected convention) or deleting it to avoid dead configuration.

Suggested change
You are a rigorous senior code reviewer tasked with preventing security vulnerabilities in code submissions.
Your assessment must be based on the code diffs of each commit.
- Language: English
- Focus on .NET security policy and best practices
- Flag any potential SQL injection, XSS, path traversal, insecure deserialization, or other OWASP Top 10 risks
- Check for hardcoded secrets, credentials, or sensitive data exposure
- Verify proper input validation and output encoding
- Ensure secure file I/O patterns (no arbitrary file access)
# Deprecated: Copilot code review instructions
This file previously contained instructions for GitHub Copilot Code Review, but it is **not**
referenced by any workflow or configuration in this repository and therefore has no effect
on automated reviews.
It is retained only for historical reference. When configuring Copilot Code Review, prefer:
- The officially supported `.github/copilot-instructions.md` file, **or**
- Explicit configuration inside your CI workflows or other documented mechanisms.
If you do not need this historical reference, you may safely delete this file.

Copilot uses AI. Check for mistakes.

IMPORTANT: Do NOT flag the following as security issues:
- Using ${{ secrets.* }} in GitHub Actions workflows (this is the correct way to use secrets in CI)
- Changes to CI/CD configuration files (.yml/.yaml under .github/workflows/) unless they contain actual hardcoded credentials
- Changes to documentation files (.md) unless they expose sensitive information
108 changes: 89 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

permissions:
contents: read
pull-requests: write
pull-requests: read

jobs:
build:
Expand Down Expand Up @@ -39,29 +39,99 @@ jobs:
name: test-results
path: '**/test-results.trx'

ai-pr-review:
ai-security-scan:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
needs: build

permissions:
contents: read
pull-requests: write

steps:
- name: Checkout
uses: actions/checkout@v4

- name: AI PR Review
uses: github/copilot-code-review-action@v1
with:
model: gpt-4o
custom_instructions: |
You are a rigorous senior code reviewer tasked with preventing security vulnerabilities in code submissions.
Your assessment must be based on the code diffs of each commit.
- Language: English
- Focus on .NET security policy and best practices
- Flag any potential SQL injection, XSS, path traversal, insecure deserialization, or other OWASP Top 10 risks
- Check for hardcoded secrets, credentials, or sensitive data exposure
- Verify proper input validation and output encoding
- Ensure secure file I/O patterns (no arbitrary file access)
fetch-depth: 0

- name: Get PR diff
id: diff
run: |
DIFF=$(git diff origin/${{ github.base_ref }}...HEAD -- '*.cs' '*.csproj' || true)
if [ -z "$DIFF" ]; then
echo "No code changes detected."
echo "skip=true" >> $GITHUB_OUTPUT
else
# Save diff to file to avoid shell escaping issues
echo "$DIFF" > /tmp/pr_diff.txt
echo "skip=false" >> $GITHUB_OUTPUT
fi

- name: AI Security Review
if: steps.diff.outputs.skip != 'true'
env:
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
AZURE_OPENAI_DEPLOYMENT: ${{ secrets.AZURE_OPENAI_DEPLOYMENT }}
run: |
DIFF=$(cat /tmp/pr_diff.txt)

# Truncate diff if too large (max ~12000 chars to fit in context)
if [ ${#DIFF} -gt 12000 ]; then
DIFF="${DIFF:0:12000}... [truncated]"
fi

INSTRUCTIONS=$(cat .github/copilot-code-review.md 2>/dev/null || echo "Review for security issues.")

API_VERSION="2025-01-01-preview"
URL="${AZURE_OPENAI_ENDPOINT%/}/openai/deployments/${AZURE_OPENAI_DEPLOYMENT}/chat/completions?api-version=${API_VERSION}"

# Build JSON payload safely using jq
PAYLOAD=$(jq -n \
--arg instructions "$INSTRUCTIONS" \
--arg diff "$DIFF" \
'{
messages: [
{ role: "system", content: $instructions },
{ role: "user", content: ("Review this code diff for security vulnerabilities in APPLICATION SOURCE CODE ONLY. Respond ONLY with a JSON object (no markdown, no code blocks): {\"passed\": true/false, \"issues\": [\"description1\", \"description2\"]}. Set passed=true if no security issues found in application code, passed=false only for real security concerns like SQL injection, XSS, path traversal, hardcoded credentials in source code, etc. Do NOT flag CI/CD workflow configuration or documentation changes as issues.\n\nDiff:\n" + $diff) }
],
temperature: 0.1
}')

RESPONSE=$(curl -s "$URL" \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d "$PAYLOAD")

# Extract content
CONTENT=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // empty')

if [ -z "$CONTENT" ]; then
echo "::error::Failed to get AI review response"
echo "$RESPONSE" | jq .
exit 1
fi

echo "=== AI Security Review Result ==="
echo "$CONTENT"
echo "================================="

# Parse JSON from response: strip markdown code blocks, then parse with jq
CLEAN_CONTENT=$(echo "$CONTENT" | sed '/^```/d')
# Use 'if .passed then "true" else "false" end' to handle boolean false correctly
PASSED=$(echo "$CLEAN_CONTENT" | jq -r 'if .passed == true then "true" elif .passed == false then "false" else "unknown" end' 2>/dev/null)

if [ "$PASSED" = "false" ]; then
echo ""
echo "::error::AI Security Review FAILED - security issues detected"
echo "$CLEAN_CONTENT" | jq -r '.issues[]?' 2>/dev/null | while read -r issue; do
echo "::warning::$issue"
done
exit 1
elif [ "$PASSED" = "true" ]; then
echo ""
echo "✅ AI Security Review PASSED - no security issues found"
else
echo "::warning::Could not parse AI review result, treating as FAIL for safety"
exit 1
fi

- name: Skip notice
if: steps.diff.outputs.skip == 'true'
run: echo "✅ No code changes to review"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ Desktop.ini

## NuGet
*.nupkg

## Wiki
MiniPdf.wiki/
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

A minimal, zero-dependency .NET library for generating PDF documents from text and Excel (.xlsx) files.

> **Security**: All PRs are automatically reviewed by Copilot AI and Azure AI security scan for vulnerabilities.

## Features

- **Text-to-PDF** — Create PDF documents with positioned or auto-wrapped text
Expand Down