Skip to content

Commit 5d2f65e

Browse files
authored
chore: configure GitHub Copilot agent environment and standardize Maven wrapper usage (#530)
1 parent c7f37dd commit 5d2f65e

5 files changed

Lines changed: 146 additions & 26 deletions

File tree

.github/copilot-environment.yml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# GitHub Copilot Agent Development Environment Configuration
2+
# This file preinstalls tools and dependencies to ensure smooth agent sessions
3+
# Documentation: https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/use-copilot-agents/coding-agent/customize-the-agent-environment
4+
5+
# Preinstall script runs once when the environment is created
6+
# Set up all required tools and dependencies
7+
preinstall: |
8+
set -e
9+
10+
echo "🔧 Setting up Hephaestus development environment..."
11+
12+
# Install Node.js 22.10.0 (exact version from .node-version)
13+
echo "📦 Installing Node.js 22.10.0..."
14+
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
15+
apt-get install -y nodejs
16+
node --version
17+
npm --version
18+
19+
# Install Java 21 (OpenJDK via Adoptium/Eclipse Temurin)
20+
echo "☕ Installing Java 21..."
21+
apt-get install -y wget apt-transport-https gnupg
22+
mkdir -p /etc/apt/keyrings
23+
wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | tee /etc/apt/keyrings/adoptium.asc
24+
echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list
25+
apt-get update
26+
apt-get install -y temurin-21-jdk
27+
java -version
28+
29+
# Install Python 3.13
30+
echo "🐍 Installing Python 3.13..."
31+
apt-get install -y software-properties-common
32+
add-apt-repository -y ppa:deadsnakes/ppa
33+
apt-get update
34+
apt-get install -y python3.13 python3.13-venv python3.13-dev python3-pip
35+
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.13 1
36+
python3 --version
37+
38+
# Install Poetry 2.x for Python dependency management
39+
echo "📝 Installing Poetry 2.x..."
40+
if ! command -v poetry &> /dev/null; then
41+
curl -sSL https://install.python-poetry.org | POETRY_VERSION=2.0.0 python3 -
42+
echo 'export PATH="/root/.local/bin:$PATH"' >> ~/.bashrc
43+
else
44+
echo "Poetry already installed: $(poetry --version)"
45+
fi
46+
export PATH="/root/.local/bin:$PATH"
47+
poetry --version
48+
49+
# Verify Docker is available (usually pre-installed in GitHub environments)
50+
echo "🐳 Checking Docker availability..."
51+
docker --version || echo "⚠️ Docker not available, some database operations may fail"
52+
53+
# Install project npm dependencies
54+
echo "📦 Installing npm dependencies..."
55+
# Always remove node_modules to ensure a clean install
56+
if [ -d "node_modules" ]; then
57+
echo "Removing existing node_modules directory..."
58+
rm -rf node_modules
59+
fi
60+
npm ci --prefer-offline --no-audit
61+
62+
# Bootstrap Python environments for intelligence-service and webhook-ingest
63+
echo "🔧 Bootstrapping Python environments..."
64+
if command -v poetry &> /dev/null; then
65+
npm run bootstrap:py || echo "⚠️ Poetry bootstrap failed, may need Python 3.13"
66+
else
67+
echo "⚠️ Poetry not available, skipping Python bootstrap"
68+
fi
69+
70+
# Verify Maven wrapper is executable
71+
echo "✅ Verifying Maven wrapper..."
72+
chmod +x server/application-server/mvnw
73+
cd server/application-server && ./mvnw --version
74+
cd ../..
75+
76+
echo "✅ Environment setup complete!"
77+
78+
# Environment variables for development sessions
79+
environment:
80+
# Database connection for local development
81+
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/hephaestus
82+
SPRING_DATASOURCE_USERNAME: root
83+
SPRING_DATASOURCE_PASSWORD: root
84+
85+
# Intelligence service model configuration (fake provider for tooling/generation)
86+
MODEL_NAME: fake:model
87+
DETECTION_MODEL_NAME: fake:model
88+
89+
# Add Poetry to PATH
90+
PATH: /root/.local/bin:$PATH

.github/copilot-instructions.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
# Additional Hints
22

3+
## Pull Request Title Format
4+
5+
When creating pull requests, follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
6+
7+
**Format**: `<type>[optional scope]: <description>`
8+
9+
**Common types**:
10+
- `fix`: Bug fixes
11+
- `feat`: New features
12+
- `docs`: Documentation changes
13+
- `refactor`: Code refactoring
14+
- `test`: Test changes
15+
- `chore`: Maintenance tasks
16+
- `ci`: CI/CD changes
17+
18+
**Scopes**: `webapp`, `application-server`, `intelligence-service`, `webhook-ingest`, `docs`, `ci`, `deps`, `config`
19+
20+
**Examples**:
21+
- `fix(webapp): correct authentication flow`
22+
- `feat(application-server): add team sync endpoint`
23+
- `chore(deps): update dependencies`
24+
25+
**Guidelines**:
26+
- Use lowercase for description
27+
- Use imperative mood ("add" not "adds")
28+
- No period at the end
29+
- Keep under 72 characters
30+
31+
See [CONTRIBUTING.md](../CONTRIBUTING.md) for complete guidelines.
32+
333
## Shadcn instructions (UI components)
434

535
If needed, check `src/components/ui` for existing components before you install new ones.

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This file governs the entire repository. Combine these guardrails with the scope
1111

1212
## 2. Toolchain & environment prerequisites
1313
- **Node.js**: Use the exact version from `.node-version` (currently 22.10.0). Stick with npm—the repo maintains `package-lock.json` and uses npm workspaces.
14-
- **Java**: JDK 21 (see `pom.xml`). Maven wrapper is checked in; run builds through `./mvnw` or `mvn` with Java 21 configured.
14+
- **Java**: JDK 21 (see `pom.xml`). Maven wrapper is checked in; **always run builds through `./mvnw`** (Maven wrapper) to ensure consistent Maven versions.
1515
- **Python**: Python 3.13 with Poetry 2.x. Both Python services keep virtualenvs inside their folders (`.venv`). Run `npm run bootstrap:py` before formatting/linting to ensure dev dependencies are installed.
1616
- **Docker & Docker Compose**: Required for database helper scripts (`scripts/db-utils.sh`) and for spinning up Postgres/Keycloak/NATS locally.
1717
- **Databases**: Default PostgreSQL DSN is `postgresql://root:root@localhost:5432/hephaestus`. The database helpers spin this up for you via Docker.
@@ -38,7 +38,7 @@ We rely heavily on generated artifacts. Never hand-edit these directories—rege
3838

3939
| Artifact | Source command |
4040
| --- | --- |
41-
| `server/application-server/openapi.yaml` | `npm run generate:api:application-server:specs` (runs `mvn verify -DskipTests=true -Dapp.profiles=specs`). |
41+
| `server/application-server/openapi.yaml` | `npm run generate:api:application-server:specs` (runs `./mvnw verify -DskipTests=true -Dapp.profiles=specs`). |
4242
| `webapp/src/api/**/*`, `webapp/src/api/@tanstack/react-query.gen.ts`, `webapp/src/api/client.gen.ts`, `webapp/src/api/types.gen.ts` | `npm run generate:api:application-server:client` (wraps `npm -w webapp run openapi-ts`). |
4343
| `server/application-server/src/main/java/de/tum/in/www1/hephaestus/intelligenceservice/**` | `npm run generate:api:intelligence-service:client` (OpenAPI Generator CLI). |
4444
| `server/intelligence-service/openapi.yaml` | `MODEL_NAME=fake:model DETECTION_MODEL_NAME=fake:model npm run generate:api:intelligence-service:specs` (delegates to `poetry run openapi`). |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
],
77
"scripts": {
88
"generate:api:application-server:clean": "shx rm -rf webapp/src/api",
9-
"generate:api:application-server:specs": "cd server/application-server && sh -c 'if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then mvn verify -DskipTests=true -Dapp.profiles=specs; else SPRING_DOCKER_COMPOSE_ENABLED=false mvn verify -DskipTests=true -Dapp.profiles=specs; fi'",
9+
"generate:api:application-server:specs": "cd server/application-server && sh -c 'if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then ./mvnw verify -DskipTests=true -Dapp.profiles=specs; else SPRING_DOCKER_COMPOSE_ENABLED=false ./mvnw verify -DskipTests=true -Dapp.profiles=specs; fi'",
1010
"generate:api:application-server:client": "npm run generate:api:application-server:clean && npm -w webapp run openapi-ts",
1111
"generate:api:application-server": "npm run generate:api:application-server:specs && npm run generate:api:application-server:client",
1212
"generate:api:intelligence-service:clean": "shx rm -rf server/application-server/src/main/java/de/tum/in/www1/hephaestus/intelligenceservice",

server/application-server/src/main/java/de/tum/in/www1/hephaestus/config/SpecsSecurityConfig.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,28 @@
2020
@Profile("specs")
2121
public class SpecsSecurityConfig {
2222

23-
private static final Map<String, Object> DEFAULT_REALM_ACCESS = Map.of(
24-
"realm_access",
25-
Map.of("roles", Collections.emptyList())
26-
);
23+
private static final Map<String, Object> DEFAULT_REALM_ACCESS = Map.of(
24+
"realm_access",
25+
Map.of("roles", Collections.emptyList())
26+
);
2727

28-
@Bean
29-
@Primary
30-
JwtDecoder specsJwtDecoder() {
31-
return token -> Jwt
32-
.withTokenValue(token)
33-
.header("alg", "none")
34-
.header("typ", "JWT")
35-
.claims(claims -> {
36-
claims.put("sub", "specs-profile-user");
37-
claims.put("preferred_username", "specs");
38-
claims.put("iss", "https://localhost/specs-profile");
39-
claims.put("aud", "hephaestus-api");
40-
// Ensure the expected realm_access structure exists so the authority converter works.
41-
claims.putAll(DEFAULT_REALM_ACCESS);
42-
})
43-
.issuedAt(Instant.now())
44-
.expiresAt(Instant.now().plusSeconds(3600))
45-
.build();
46-
}
28+
@Bean
29+
@Primary
30+
JwtDecoder specsJwtDecoder() {
31+
return token ->
32+
Jwt.withTokenValue(token)
33+
.header("alg", "none")
34+
.header("typ", "JWT")
35+
.claims(claims -> {
36+
claims.put("sub", "specs-profile-user");
37+
claims.put("preferred_username", "specs");
38+
claims.put("iss", "https://localhost/specs-profile");
39+
claims.put("aud", "hephaestus-api");
40+
// Ensure the expected realm_access structure exists so the authority converter works.
41+
claims.putAll(DEFAULT_REALM_ACCESS);
42+
})
43+
.issuedAt(Instant.now())
44+
.expiresAt(Instant.now().plusSeconds(3600))
45+
.build();
46+
}
4747
}

0 commit comments

Comments
 (0)