Skip to content

Update copilot-setup-steps.yml #261

Update copilot-setup-steps.yml

Update copilot-setup-steps.yml #261

name: "Copilot Setup Steps"
# Automatically run the setup steps when they are changed to allow for easy validation, and
# allow manual testing through the repository's "Actions" tab
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
env:
GITHUB_TOKEN: ${{ secrets.COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN }}
GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN }}
DISPLAY: ":99"
jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-26.04
# Set the permissions to the lowest permissions possible needed for your steps.
# Copilot will be given its own token for its operations.
permissions:
contents: read
actions: read
attestations: read
checks: read
deployments: read
issues: write
models: read
discussions: read
pages: read
pull-requests: write
security-events: read
statuses: read
# Steps run before the agent starts working
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Cache APT packages for faster installs
- name: Cache APT packages
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: /var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/copilot-setup-steps.yml') }}
restore-keys: |
${{ runner.os }}-apt-
# Setup complete Web test environment
- name: Setup Web Test Environment (Chrome + Xvfb + Dependencies)
run: |
echo "🔧 Setting up complete Web test environment..."
# Install system dependencies for Web rendering
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
xvfb dbus-x11 x11-utils \
libgtk2.0-0 libgtk-3-0 libgbm-dev libgbm1 \
libnotify-dev libnss3 libxss1 \
libxtst6 xauth \
graphviz ffmpeg \
fonts-noto fonts-noto-cjk fonts-noto-cjk-extra \
ca-certificates fonts-liberation \
libatk-bridge2.0-0 libatk1.0-0 libcups2 \
libdbus-1-3 libdrm2 libnspr4 \
libx11-xcb1 libxcomposite1 libxdamage1 \
libxfixes3 libxrandr2 libxrender1 \
libxshmfence1 xdg-utils wget libxkbcommon0 xkb-data
# Setup D-Bus for Chrome
sudo mkdir -p /var/run/dbus
sudo dbus-daemon --system --fork || true
echo "✅ Web test environment setup complete"
env:
DISPLAY: ":99"
XKB_DEFAULT_RULES: evdev
XKB_DEFAULT_MODEL: pc105
XKB_DEFAULT_LAYOUT: us
# JavaScript/TypeScript setup
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "24"
- name: Cache dependencies
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
# Pre-install MCP server packages globally
- name: Install MCP server packages globally
run: |
echo "📦 Installing MCP server packages globally..."
# Install Node.js MCP servers that exist on npm
npm install -g @modelcontextprotocol/server-filesystem
npm install -g @modelcontextprotocol/server-memory
npm install -g @modelcontextprotocol/server-sequential-thinking
# Pre-cache @playwright/mcp for faster startup
npm install -g @playwright/mcp
echo "✅ Node.js MCP server packages installed globally"
# Cache global npm packages for MCP servers
- name: Cache global npm packages
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.npm
/usr/local/lib/node_modules
/usr/local/bin/mcp-server-*
key: ${{ runner.os }}-mcp-servers-v4-${{ hashFiles('.github/copilot-mcp.json') }}
restore-keys: |
${{ runner.os }}-mcp-servers-v4-
# Verify all MCP server installations
- name: Verify MCP server installations
run: |
echo "🔍 Verifying MCP server installations..."
echo "=== Node.js MCP Servers ==="
echo "Checking mcp-server-filesystem..."
which mcp-server-filesystem && echo "✅ mcp-server-filesystem found" || echo "❌ mcp-server-filesystem NOT found"
echo "Checking mcp-server-memory..."
which mcp-server-memory && echo "✅ mcp-server-memory found" || echo "❌ mcp-server-memory NOT found"
echo "Checking mcp-server-sequential-thinking..."
which mcp-server-sequential-thinking && echo "✅ mcp-server-sequential-thinking found" || echo "❌ mcp-server-sequential-thinking NOT found"
echo "Checking @playwright/mcp..."
which mcp-server-playwright 2>/dev/null && echo "✅ mcp-server-playwright found" || echo "ℹ️ @playwright/mcp available via npx"
echo ""
echo "=== HTTP MCP Servers ==="
echo "📍 GitHub MCP Server: Using HTTP endpoint (https://api.githubcopilot.com/mcp/insiders)"
echo "✅ MCP server verification complete"
- name: Set up JDK 26
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: "temurin"
java-version: "26"
# Disable built-in cache - we use optimized manual caching below
cache: ""
# Optimized Maven caching with multiple fallback levels for better resilience
- name: Cache Maven dependencies
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.m2/repository
~/.m2/wrapper
~/.sonar/cache
# Include Maven version in key for isolation
key: ${{ runner.os }}-maven-3.9.16-${{ hashFiles('**/pom.xml', '.mvn/**') }}
restore-keys: |
${{ runner.os }}-maven-3.9.16-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-3.9.16-
${{ runner.os }}-maven-
- name: Cache APT packages
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: /var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/copilot-setup-steps.yml') }}
restore-keys: |
${{ runner.os }}-apt-
- name: APT update
run: sudo apt-get update
- name: Install buildtools and PostgreSQL
run: sudo apt-get install -y graphviz build-essential fakeroot devscripts debhelper dh-make wget ant postgresql-18 postgresql-contrib-18 postgresql-18-pgaudit postgresql-18-pgvector
- name: Create PostgreSQL 18 cluster
run: |
# Drop pre-installed PostgreSQL clusters that block port 5432
sudo pg_dropcluster --stop 14 main || true
sudo pg_dropcluster --stop 16 main || true
# Create and start PostgreSQL 18 cluster (idempotent)
if sudo pg_lsclusters 18 main >/dev/null 2>&1; then
sudo pg_ctlcluster 18 main start
else
sudo pg_createcluster 18 main --start
fi
- name: Configure PostgreSQL
run: |
# Enable prepared transactions and required extensions
sudo sed -i "s/#max_prepared_transactions = 0/max_prepared_transactions = 100/" /etc/postgresql/18/main/postgresql.conf
sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = 'pg_stat_statements, pgaudit, pgcrypto, auto_explain'/" /etc/postgresql/18/main/postgresql.conf
echo "pgaudit.log = ddl" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "pg_stat_statements.track = all" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "pg_stat_statements.max = 10000" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Performance optimization settings per README-SCHEMA-MAINTENANCE.md
# Memory settings (adjusted for GitHub Actions ~7GB RAM, lower than production recommendations)
echo "shared_buffers = '1GB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "effective_cache_size = '4GB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "work_mem = '32MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "maintenance_work_mem = '256MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Checkpoint settings for write performance
echo "checkpoint_completion_target = 0.9" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "wal_buffers = '16MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "max_wal_size = '2GB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "min_wal_size = '512MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Query planning optimizations (SSD storage on GitHub Actions)
echo "random_page_cost = 1.1" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "effective_io_concurrency = 200" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Connection settings (reduced for CI environment)
echo "max_connections = 100" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Extended Statistics for Better Query Planning
# Note: default_statistics_target = 100 is PostgreSQL's default, but explicitly set for documentation clarity
echo "default_statistics_target = 100" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "constraint_exclusion = partition" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Auto-Explain Extension for Automatic Query Plan Logging
echo "auto_explain.log_min_duration = 1000" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "auto_explain.log_analyze = true" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "auto_explain.log_buffers = true" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "auto_explain.log_timing = true" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "auto_explain.log_verbose = true" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Enhanced pg_stat_statements Configuration
echo "pg_stat_statements.track_planning = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "pg_stat_statements.track_utility = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Query Planner Settings for View Analysis
echo "enable_partitionwise_join = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "enable_partitionwise_aggregate = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "jit = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "jit_above_cost = 100000" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Statistics Collection Enhancement
echo "track_activities = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "track_counts = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "track_io_timing = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "track_functions = all" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Logging for Query Analysis
echo "log_min_duration_statement = 1000" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "log_statement = 'ddl'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Add IPv6 loopback access
echo "host all all ::1/128 md5" | sudo tee -a /etc/postgresql/18/main/pg_hba.conf
- name: Generate SSL certificates for PostgreSQL
run: |
# Generate secure random passphrase
openssl rand -base64 48 > passphrase.txt
# Create passphrase-protected private key (increased to 4096 bits)
openssl genrsa -des3 -passout file:passphrase.txt -out server.pass.key 4096
# Remove passphrase protection from private key
openssl rsa -passin file:passphrase.txt -in server.pass.key -out server.key
rm server.pass.key
# Create OpenSSL config file with Subject Alternative Names
cat > openssl.cnf <<EOL
[req]
default_bits = 4096
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
C=UK
ST=PostgreSQL
L=Docker
O=Hack23
OU=demo
CN=localhost
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
EOL
# Create Certificate Signing Request with config
openssl req -new -key server.key -out server.csr -config openssl.cnf
# Self-sign the certificate with extensions (valid for 10 years)
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -extensions req_ext -extfile openssl.cnf
# Clean up temporary files
rm passphrase.txt server.csr openssl.cnf
- name: Deploy SSL certificate and key for PostgreSQL
run: |
# Secure the certificate files
chmod 600 server.key server.crt
# Copy certificate and key to PostgreSQL data directory
sudo cp server.crt /var/lib/postgresql/18/main/server.crt
sudo cp server.key /var/lib/postgresql/18/main/server.key
# Secure the certificate and key
sudo chmod 600 /var/lib/postgresql/18/main/server.key
sudo chmod 644 /var/lib/postgresql/18/main/server.crt
sudo chown postgres:postgres /var/lib/postgresql/18/main/server.key
sudo chown postgres:postgres /var/lib/postgresql/18/main/server.crt
# Enable SSL in PostgreSQL
echo "ssl = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "ssl_cert_file = '/var/lib/postgresql/18/main/server.crt'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "ssl_key_file = '/var/lib/postgresql/18/main/server.key'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Provide SSL certificate to the runner user
mkdir -p $HOME/.postgresql
cp server.crt $HOME/.postgresql/root.crt
chmod 600 $HOME/.postgresql/root.crt
# Clean up
rm server.key server.crt
# Restart PostgreSQL to apply all changes
sudo systemctl restart postgresql
- name: Create CIA database and user
run: |
sudo -u postgres psql -c "CREATE USER eris WITH PASSWORD 'discord';"
sudo -u postgres psql -c "CREATE DATABASE cia_dev;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE cia_dev TO eris;"
sudo -u postgres psql -c "ALTER USER eris WITH SUPERUSER;"
sudo -u postgres psql -d cia_dev -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"
sudo -u postgres psql -d cia_dev -c "CREATE EXTENSION IF NOT EXISTS pgaudit;"
sudo -u postgres psql -d cia_dev -c "CREATE EXTENSION IF NOT EXISTS pgcrypto;"
sudo -u postgres psql -d cia_dev -c "GRANT ALL ON SCHEMA public TO eris;"
sudo -u postgres psql -d cia_dev -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO eris;"
sudo -u postgres psql -d cia_dev -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO eris;"
sudo -u postgres psql -d cia_dev -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON FUNCTIONS TO eris;"
- name: Load database schema
run: |
# Load the full schema into the database
sudo -u postgres psql -d cia_dev -f service.data.impl/src/main/resources/full_schema.sql || echo "Schema load completed with warnings (expected for first-time setup)"
# Verify schema loaded successfully by checking for key tables
echo "Verifying schema loaded..."
sudo -u postgres psql -d cia_dev -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';" || echo "Schema verification completed"
- name: Generate statistics for view analysis
run: |
# Run ANALYZE on all tables to generate statistics
echo "Generating table statistics for accurate EXPLAIN analysis..."
sudo -u postgres psql -d cia_dev -c "ANALYZE;"
# Verify statistics were generated
echo "Verifying statistics collection..."
sudo -u postgres psql -d cia_dev -c "SELECT schemaname, relname, last_analyze, last_autoanalyze FROM pg_stat_user_tables ORDER BY relname LIMIT 20;"
# Show current statistics targets
echo "Sample statistics for verification..."
sudo -u postgres psql -d cia_dev -c "SELECT tablename, attname, n_distinct, correlation FROM pg_stats WHERE schemaname = 'public' ORDER BY tablename LIMIT 20;"
- name: Verify PostgreSQL SSL configuration
run: |
# Verify SSL is enabled
sudo -u postgres psql -c "SHOW ssl;" | grep on
# Verify prepared transactions are enabled
sudo -u postgres psql -c "SHOW max_prepared_transactions;" | grep 100
# Verify extensions are loaded
sudo -u postgres psql -d cia_dev -c "\dx" | grep pg_stat_statements
sudo -u postgres psql -d cia_dev -c "\dx" | grep pgaudit
sudo -u postgres psql -d cia_dev -c "\dx" | grep pgcrypto
# Test SSL connection from localhost
echo "Testing SSL connection..."
PGPASSWORD=discord PGSSLMODE=require psql -h localhost -U eris -d cia_dev -c "SELECT version();" || echo "SSL connection test completed"
- name: Set up Maven
uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5
with:
maven-version: 3.9.16
- name: Build with Maven
run: mvn -B clean install --file pom.xml -Prelease-site,all-modules -DskipTests -DfailIfNoTests=false -Dsurefire.failIfNoSpecifiedTests=false -Dspdx.skip=true -Dmaven.wagon.http.retryHandler.count=3 -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.pool=true
- name: Run all unit tests (excluding integration tests)
run: mvn -B test --file pom.xml -Prelease-site,all-modules -Dtest='!**ITest*,!**/XmlDateTypeAdapterTest,!**/XmlTimeTypeAdapterTest,!**/XmlDateTimeTypeAdapterTest' -DfailIfNoTests=false -Dsurefire.failIfNoSpecifiedTests=false -Dspdx.skip=true -Dmaven.wagon.http.retryHandler.count=3 -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.pool=true
continue-on-error: true