Blueprints prêts à l’emploi pour les langages courants, les registres privés et les infrastructures d’entreprise.
Des blueprints prêts à l’emploi pour les langages et cas d’usage courants. Chaque modèle est autonome. Combinez-les pour créer votre configuration complète.Pour une présentation détaillée de chaque champ, consultez la Référence des blueprints.
Secrets : Les modèles font référence à des secrets via $SECRET_NAME. Configurez-les dans Settings > Secrets avant d’utiliser un modèle. N’intégrez jamais d’identifiants en dur dans votre blueprint.
Blueprints minimaux pour les configurations les plus courantes. Copiez-en un, collez-le dans l’éditeur de blueprints, et le tour est joué.
Projet Node.js
initialize: | npm install -g pnpmmaintenance: | pnpm installknowledge: - name: lint contents: | Exécutez `pnpm lint` pour vérifier les erreurs. - name: test contents: | Exécutez `pnpm test` pour lancer la suite complète.
Projet Python
initialize: | curl -LsSf https://astral.sh/uv/install.sh | shmaintenance: | uv syncknowledge: - name: lint contents: | Exécutez `uv run ruff check .` pour lancer le lint. - name: test contents: | Exécutez `uv run pytest` pour lancer la suite complète.
Étapes de build propres à chaque dépôt, gestion des dépendances et entrées Knowledge. Définissez-les dans Settings > Configuration de l’environnement > [votre dépôt].
initialize: | nvm install 20 nvm use 20maintenance: | npm installknowledge: - name: lint contents: | npx eslint . - name: test contents: | npm test - name: build contents: | npm run build
Utilisez npm install (et non npm ci) dans maintenance. Cette commande effectue une mise à jour incrémentielle, tandis que npm ci supprime node_modules et réinstalle tout depuis zéro à chaque session.
Rust (via rustup) et Cargo sont préinstallés sur l’image de base de Devin. Passez l’étape d’installation si la toolchain stable par défaut vous convient. Il vous suffit de récupérer les dépendances.
Monorepo avec un frontend Node.js et un backend Python. Chaque sous-projet a ses propres entrées Knowledge.
initialize: - name: Installer pnpm run: npm install -g pnpm - name: Installer uv run: curl -LsSf https://astral.sh/uv/install.sh | shmaintenance: - name: Installer les dépendances du frontend run: (cd packages/frontend && pnpm install) - name: Installer les dépendances du backend run: (cd packages/backend && uv sync) - name: Build de la bibliothèque partagée run: (cd packages/shared && pnpm install && pnpm build)knowledge: - name: structure contents: | Il s'agit d'un monorepo avec trois packages : - `packages/frontend` — application React (TypeScript, pnpm) - `packages/backend` — API Python (FastAPI, uv) - `packages/shared` — utilitaires TypeScript partagés (doivent être buildés avant le frontend) - name: frontend contents: | Exécutez `cd packages/frontend && pnpm dev` pour démarrer le serveur de développement. Exécutez `cd packages/frontend && pnpm lint` pour lancer le linting. Exécutez `cd packages/frontend && pnpm test` pour lancer les tests. - name: backend contents: | Exécutez `cd packages/backend && uv run uvicorn app.main:app --reload` pour démarrer l'API. Exécutez `cd packages/backend && uv run ruff check .` pour lancer le linting. Exécutez `cd packages/backend && uv run pytest` pour lancer les tests.
Utilisez des subshells (cd dir && command) plutôt que cd dir && command afin que le répertoire de travail soit réinitialisé entre les étapes.
Monorepo Java dans lequel différents services nécessitent différentes versions de JDK. Installez les deux JDK lors de l’initialisation, puis utilisez les entrées knowledge pour indiquer à Devin quelle valeur de JAVA_HOME utiliser pour chaque service.
initialize: - name: Installer JDK 17 (principal) run: | sudo apt-get update -qq sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-17-jdk-headless echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' \ | sudo tee /etc/profile.d/java.sh > /dev/null - name: Installer JDK 11 (service ancien) run: | sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-11-jdk-headlessmaintenance: - name: Préchauffer les caches de dépendances run: | export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 (cd services/api && ./gradlew dependencies --refresh-dependencies) export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 (cd services/legacy && ./gradlew dependencies --refresh-dependencies)knowledge: - name: build_api contents: | Builder le service API (JDK 17) : JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \ cd services/api && ./gradlew clean build - name: build_legacy contents: | Builder le service ancien (JDK 11) : JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \ cd services/legacy && ./gradlew clean build - name: test_all contents: | Exécuter les tests pour tous les services : JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \ (cd services/api && ./gradlew test) JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \ (cd services/legacy && ./gradlew test)
Configurez les gestionnaires de paquets pour résoudre les dépendances depuis des registres privés. Définissez cela dans Settings > Environment configuration > setup à l’échelle de l’organisation (ou au niveau du dépôt si un seul dépôt est concerné).
La configuration des identifiants doit se faire dans maintenance, pas dans initialize. Les étapes qui écrivent des secrets (mots de passe de registre, jetons d’authentification) dans des fichiers de configuration doivent utiliser maintenance afin que les identifiants soient
rechargés au début de chaque session. Les secrets sont supprimés avant l’enregistrement du snapshot, donc les fichiers de configuration écrits pendant initialize n’auront pas d’identifiants valides au démarrage.
Si votre registre privé utilise une autorité de certification d’entreprise, assurez-vous que le certificat d’autorité de certification est d’abord installé au niveau Enterprise. La configuration ci-dessous suppose que la confiance HTTPS est
déjà établie.
Configurez npm pour récupérer les packages d’un scope (par ex. @myorg/*) à partir d’un registre privé, tandis que les packages publics continuent de provenir du registre npm par défaut.
Secrets requis
- GITHUB_PACKAGES_TOKEN — Jeton d’accès personnel ou jeton GitHub App avec le périmètre read:packages
maintenance: - name: Configure npm scoped registry run: | npm config set @myorg:registry https://npm.pkg.github.com npm config set //npm.pkg.github.com/:_authToken $GITHUB_PACKAGES_TOKEN
Remplacez @myorg par votre scope npm. URL courantes de registres privés :
Faites passer tous les packages npm par votre registre privé (et pas seulement les packages d’un scope).
Secrets requis
NPM_REGISTRY_URL — URL complète de votre registre npm (par ex. https://artifactory.example.com/artifactory/api/npm/npm-virtual) - NPM_REGISTRY_HOST — Nom d’hôte uniquement, sans protocole (par ex.
artifactory.example.com) - REGISTRY_TOKEN — Jeton d’authentification npm pour le registre
maintenance: - name: Configure npm to use private registry run: | npm config set registry $NPM_REGISTRY_URL npm config set //${NPM_REGISTRY_HOST}/:_authToken $REGISTRY_TOKEN npm config set strict-ssl true
Configurez pnpm pour récupérer des packages à partir d’un registre privé.
Secrets requis
NPM_REGISTRY_URL — URL complète de votre registre npm - NPM_REGISTRY_HOST — Nom d’hôte uniquement, sans protocole - REGISTRY_TOKEN — Jeton d’authentification npm pour le registre
initialize: - name: Install pnpm run: npm install -g pnpmmaintenance: - name: Configure pnpm for private registry run: | pnpm config set registry $NPM_REGISTRY_URL pnpm config set //${NPM_REGISTRY_HOST}/:_authToken $REGISTRY_TOKEN
Configurez Yarn (Classic v1 ou Berry v2+) pour récupérer des packages à partir d’un registre privé.
Secrets requis
- NPM_REGISTRY_URL — URL complète de votre registre npm/Yarn - REGISTRY_TOKEN — Jeton d’authentification pour le registre (Berry uniquement)
Yarn Classic (v1) :
initialize: - name: Install Yarn Classic run: npm install -g yarnmaintenance: - name: Configure Yarn for private registry run: | yarn config set registry "$NPM_REGISTRY_URL" # Pour les packages d’un scope : # yarn config set @myorg:registry "https://npm.pkg.github.com"
Yarn Berry (v2+) :
maintenance: - name: Configure Yarn Berry for private registry run: | yarn config set npmRegistryServer "$NPM_REGISTRY_URL" yarn config set npmAuthToken "$REGISTRY_TOKEN" # Pour les packages d’un scope : # yarn config set npmScopes.myorg.npmRegistryServer "https://npm.pkg.github.com" # yarn config set npmScopes.myorg.npmAuthToken "$GITHUB_PACKAGES_TOKEN"
Configurez pip et uv pour récupérer les packages depuis votre registre PyPI privé (p. ex., Nexus, Artifactory).
Secrets requis
PYPI_REGISTRY_URL — URL complète de votre index PyPI, y compris les identifiants si nécessaire (p. ex., https://user:token@nexus.example.com/repository/pypi-proxy/simple)
Configurez Poetry pour récupérer les packages depuis un registre PyPI privé.
Secrets requis
POETRY_REGISTRY_URL — URL complète de votre registre compatible PyPI - REGISTRY_USER — Nom d’utilisateur du registre - REGISTRY_PASS — Mot de passe du registre ou jeton d’API
Installez le JDK et configurez Maven pour faire transiter toute la résolution des dépendances par votre registre privé (p. ex. Artifactory, Nexus).
Le JDK 17 est préinstallé sur l’image de base de Devin. Passez l’étape d’installation si l’OpenJDK 17 par défaut vous suffit. Vous n’avez besoin que de l’installation de Maven et de la configuration du registre.
Secrets requis
MAVEN_REGISTRY_URL — URL de votre registre Maven (p. ex. https://artifactory.example.com/artifactory/maven-virtual) - REGISTRY_USER — Nom d’utilisateur du registre - REGISTRY_PASS — Mot de passe du registre ou
jeton d’API
Installez le JDK et configurez Gradle pour résoudre l’ensemble des dépendances via votre registre privé.
Le JDK 17 est préinstallé sur l’image de base de Devin. Ignorez l’étape d’installation du JDK si la version par défaut vous convient.
Secrets requis
- GRADLE_REGISTRY_URL — URL de votre registre Gradle/Maven - REGISTRY_USER — Nom d’utilisateur du registre - REGISTRY_PASS — Mot de passe du registre ou jeton d’API
Installez Go et configurez-le pour passer par un proxy de modules privé afin de résoudre les modules (par ex., Athens, Artifactory ou un endpoint GOPROXY).
Secrets requis
GO_PROXY_URL — URL de votre proxy de modules Go (par ex., https://athens.corp.internal) - GIT_TOKEN — jeton d’accès personnel pour les dépôts Git privés qui hébergent des modules Go
initialize: - name: Install Go run: | GO_VERSION=1.23.5 ARCH=$(dpkg --print-architecture) curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz" \ | sudo tar -xz -C /usr/local echo 'export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"' \ | sudo tee /etc/profile.d/golang.sh > /dev/null - name: Configure Go for private modules run: | cat << 'GOENV' | sudo tee /etc/profile.d/go-private.sh > /dev/null export GOPROXY="$GO_PROXY_URL,direct" export GONOSUMCHECK="corp.internal/*,github.com/myorg/*" export GOPRIVATE="corp.internal/*,github.com/myorg/*" GOENVmaintenance: - name: Authenticate Go private modules run: | git config --global url."https://$GIT_TOKEN@github.com/myorg/".insteadOf "https://github.com/myorg/"
Configurez Docker pour récupérer des images depuis un registre de conteneurs privé.
Secrets requis
DOCKER_MIRROR_URL(facultatif) — URL de votre miroir Docker Hub (par exemple, https://mirror.corp.internal) - DOCKER_REGISTRY_URL — URL de votre registre de conteneurs privé (par exemple,
registry.corp.internal:5000) - DOCKER_REGISTRY_USER — Nom d’utilisateur du registre - DOCKER_REGISTRY_PASS — Mot de passe du registre ou jeton d’API
initialize: - name: Create Docker config directory run: sudo mkdir -p /etc/dockermaintenance: - name: Configure Docker for private registry run: | # Configurer le miroir de registre (facultatif — achemine les pulls Docker Hub via votre registre) cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null { "registry-mirrors": ["$DOCKER_MIRROR_URL"] } EOF sudo systemctl restart docker || true # Se connecter au registre de conteneurs privé echo "$DOCKER_REGISTRY_PASS" | docker login "$DOCKER_REGISTRY_URL" \ --username "$DOCKER_REGISTRY_USER" \ --password-stdin
Configurez Cargo pour utiliser des crates provenant d’un registre privé.
Rust (via rustup) et Cargo sont préinstallés sur l’image de base de Devin. Passez l’étape d’installation si la toolchain stable par défaut suffit. Seule la configuration du registre est nécessaire.
Secrets requis
CARGO_REGISTRY_INDEX — URL de l’index du registre privé (p. ex., sparse+https://cargo.corp.internal/api/v1/crates/) - CARGO_REGISTRY_TOKEN — jeton d’authentification pour le registre privé
Si vous devez simplement ajouter un registre privé sans remplacer crates.io, supprimez les sections [source.crates-io] et [source.private], puis utilisez cargo install --registry private ou [dependencies] my-crate = { version = "1.0", registry = "private" } dans Cargo.toml.
Ruby / Bundler
Installez Ruby et configurez Bundler pour récupérer les gems depuis un serveur de gems privé.
Secrets requis
GEM_SERVER_URL — URL de votre serveur de gems privé (p. ex., https://artifactory.example.com/artifactory/api/gems/gems-virtual) - REGISTRY_USER — Nom d’utilisateur du registre - REGISTRY_PASS — Mot de passe du registre
ou jeton d’API
initialize: - name: Install Ruby run: | sudo apt-get update -qq sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ruby-fullmaintenance: - name: Configure Bundler for private gem server run: | bundle config set mirror.https://rubygems.org "$GEM_SERVER_URL" bundle config set "$GEM_SERVER_URL" "$REGISTRY_USER:$REGISTRY_PASS"
Schémas d’URL courants pour les serveurs de gems :
Les jetons AWS CodeArtifact expirent après 12 heures. Utilisez maintenance pour actualiser le jeton au début de chaque session. Cet exemple configure npm, pip et Maven pour utiliser CodeArtifact.
awscli est préinstallé sur l’image de base de Devin. Il vous suffit d’actualiser le jeton et de configurer le registre.
Secrets requis
AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY — Identifiants IAM avec les autorisations codeartifact:GetAuthorizationToken et sts:GetServiceBearerToken - CA_DOMAIN — Nom de votre domaine CodeArtifact
CA_DOMAIN_OWNER — ID du compte AWS propriétaire du domaine - CA_REGION — Région AWS (p. ex., us-east-1) - CA_NPM_REPO, CA_PYPI_REPO, CA_MAVEN_REPO — Noms des dépôts pour chaque écosystème
Infrastructure au niveau des machines qui s’applique à l’ensemble des organisations et des dépôts. Définissez ces paramètres dans Settings > environnement de base de Devin (à l’échelle de l’entreprise) ou Settings > configuration de l’environnement > configuration à l’échelle de l’organisation (à l’échelle de l’organisation).
Votre organisation utilise une autorité de certification privée pour ses services internes. Devin a besoin du certificat racine pour accéder aux dépôts et outils internes via HTTPS.
Secrets requis
- CORP_ROOT_CA_B64 — certificat PEM encodé en Base64 issu de votre autorité de certification d’entreprise. Générez-le avec : cat corp-root-ca.crt | base64 -w0
Si votre organisation utilise plusieurs certificats d’autorité de certification (par exemple, des autorités de certification distinctes pour différents services internes).
Secrets requis
- CORP_ROOT_CA_B64 — certificat principal d’autorité de certification encodé en Base64 - CORP_INTERMEDIATE_CA_B64 — certificat intermédiaire d’autorité de certification encodé en Base64
initialize: - name: Install corporate CA certificates run: | echo "$CORP_ROOT_CA_B64" | base64 -d \ | sudo tee /usr/local/share/ca-certificates/corp-root-ca.crt > /dev/null echo "$CORP_INTERMEDIATE_CA_B64" | base64 -d \ | sudo tee /usr/local/share/ca-certificates/corp-intermediate-ca.crt > /dev/null sudo update-ca-certificates # Créer un bundle combiné pour les outils nécessitant un seul fichier CA cat /usr/local/share/ca-certificates/corp-*.crt \ | sudo tee /usr/local/share/ca-certificates/corp-bundle.crt > /dev/null echo 'export NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/corp-bundle.crt' \ | sudo tee /etc/profile.d/node-ca.sh > /dev/null
Proxy HTTP/HTTPS
Faites passer tout le trafic réseau par un proxy d’entreprise.
Secrets requis
CORP_HTTP_PROXY — URL du proxy HTTP (p. ex., http://proxy.corp.example.com:8080) - CORP_HTTPS_PROXY — URL du proxy HTTPS - CORP_NO_PROXY — liste d’hôtes, séparés par des virgules, à ne pas faire passer par le proxy (p. ex.,
localhost,127.0.0.1,.corp.example.com)
Si votre proxy d’entreprise nécessite une authentification par nom d’utilisateur et mot de passe.
Secrets requis
PROXY_USER — Nom d’utilisateur du proxy - PROXY_PASS — Mot de passe du proxy - PROXY_HOST — Nom d’hôte et port du proxy (par ex., proxy.corp.example.com:8080) - CORP_NO_PROXY — Hôtes à exclure du proxy
certificat d’autorité de certification + proxy (combinés)
Configuration combinée pour les environnements nécessitant à la fois une autorité de certification d’entreprise et un proxy. Ce cas est fréquent dans les environnements d’entreprise où les services internes utilisent des certificats privés et où tout le trafic doit transiter par un proxy.
Secrets requis
CORP_ROOT_CA_B64 — certificat d’autorité de certification d’entreprise encodé en Base64 - CORP_HTTP_PROXY, CORP_HTTPS_PROXY — URL du proxy - CORP_NO_PROXY — hôtes à exclure du proxy
Vos registres privés, serveurs Git ou autres services internes ne sont accessibles que via un VPN. Ce module doit s’exécuter avant les autres modules qui nécessitent un accès réseau aux ressources internes.
Secrets requis
OpenVPN :
VPN_CONFIG_B64 — Fichier de configuration OpenVPN encodé en Base64 (.ovpn). Générez-le avec : cat corp.ovpn | base64 -w0
VPN_AUTH_USER(facultatif) — Nom d’utilisateur du VPN, si votre VPN nécessite une authentification par nom d’utilisateur et mot de passe
VPN_AUTH_PASS(facultatif) — Mot de passe du VPN
WireGuard :
WG_CONFIG_B64 — Fichier de configuration WireGuard encodé en Base64. Générez-le avec : cat wg0.conf | base64 -w0
OpenVPN :
initialize: - name: Install and configure OpenVPN run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openvpn # Écrire la configuration VPN sudo mkdir -p /etc/openvpn/client echo "$VPN_CONFIG_B64" | base64 -d \ | sudo tee /etc/openvpn/client/corp.conf > /dev/null # Si le VPN requiert une authentification par nom d'utilisateur/mot de passe if [ -n "${VPN_AUTH_USER:-}" ] && [ -n "${VPN_AUTH_PASS:-}" ]; then printf '%s\n%s\n' "$VPN_AUTH_USER" "$VPN_AUTH_PASS" \ | sudo tee /etc/openvpn/client/auth.txt > /dev/null sudo chmod 600 /etc/openvpn/client/auth.txt echo "auth-user-pass /etc/openvpn/client/auth.txt" \ | sudo tee -a /etc/openvpn/client/corp.conf > /dev/null fi # Démarrer le tunnel VPN sudo systemctl daemon-reload sudo systemctl enable --now openvpn-client@corp # Attendre que le tunnel soit établi for i in $(seq 1 30); do if ip link show tun0 >/dev/null 2>&1; then break; fi sleep 1 done
Votre organisation exige que tous les commits Git soient signés, et vous souhaitez que GitHub marque les commits de Devin comme Verified.
Secrets requis
GPG_PRIVATE_KEY_B64 — Clé privée GPG encodée en Base64. Générez-la avec : gpg --export-secret-keys <key-id> | base64 -w0
GIT_USER_NAME — Nom de l’auteur Git (p. ex., Devin AI)
GIT_USER_EMAIL — Adresse e-mail de l’auteur Git. Doit correspondre à un UID de la clé GPG, sinon GitHub ne vérifiera pas la signature.
Importez également la clé publique correspondante dans le compte GitHub dont Devin utilise les identifiants pour effectuer le push (dans GitHub Settings > SSH and GPG keys). GitHub ne marque les commits comme Verified que lorsque la clé publique de signature est enregistrée sur le compte auteur du commit.
initialize: - name: Prepare GPG and git signing config run: | # Permettre à GPG de fonctionner sans TTY echo 'export GPG_TTY=$(tty)' | sudo tee -a /etc/profile.d/gpg.sh > /dev/nullmaintenance: - name: Import GPG key and configure git signing run: | echo "$GPG_PRIVATE_KEY_B64" | base64 -d | gpg --batch --import 2>/dev/null KEY_ID=$(gpg --list-secret-keys --keyid-format long 2>/dev/null \ | grep sec | head -1 | awk '{print $2}' | cut -d'/' -f2) git config --global user.signingkey "$KEY_ID" git config --global commit.gpgsign true git config --global tag.gpgsign true git config --global gpg.program gpg
Identité Git et clés SSH
Configurez l’identité Git et les clés SSH de Devin pour accéder à des serveurs Git privés.
Secrets requis
GIT_USER_NAME — Nom de l’auteur Git - GIT_USER_EMAIL — Adresse e-mail de l’auteur Git - SSH_PRIVATE_KEY_B64 — Clé privée SSH encodée en Base64. Générez-la avec : cat ~/.ssh/id_ed25519 | base64 -w0 -
SSH_KNOWN_HOSTS_B64 — Entrées du fichier known_hosts encodées en Base64. Générez-les avec : ssh-keyscan git.corp.internal | base64 -w0 - SSH_CONFIG_B64(facultatif) — Fichier de configuration SSH encodé en Base64
initialize: - name: Configure git identity run: | git config --global user.name "$GIT_USER_NAME" git config --global user.email "$GIT_USER_EMAIL" # Préparer le répertoire SSH mkdir -p ~/.ssh && chmod 700 ~/.sshmaintenance: - name: Install SSH keys run: | # Installer la clé privée SSH (dans maintenance pour qu'elle soit rechargée à neuf à chaque session) echo "$SSH_PRIVATE_KEY_B64" | base64 -d > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 # Ajouter les hôtes connus de votre serveur Git echo "$SSH_KNOWN_HOSTS_B64" | base64 -d >> ~/.ssh/known_hosts # Installer éventuellement une configuration SSH personnalisée if [ -n "${SSH_CONFIG_B64:-}" ]; then echo "$SSH_CONFIG_B64" | base64 -d > ~/.ssh/config chmod 600 ~/.ssh/config fi
Générez l’entrée known_hosts de votre serveur Git avec ssh-keyscan git.corp.internal | base64 -w0.
Installez les packages système qui ne figurent pas dans l’image Devin par défaut (p. ex., des bibliothèques natives pour le traitement d’images ou la génération de PDF).
Définissez des variables d’environnement persistantes qui doivent être disponibles dans chaque session.L’approche recommandée consiste à écrire des lignes KEY=VALUE dans le fichier $ENVRC. Les variables écrites dans $ENVRC sont automatiquement exportées pour toutes les étapes suivantes ainsi que pour la session Devin (comme avec le $GITHUB_ENV de GitHub Actions).
Les deux approches fonctionnent. $ENVRC est plus simple et recommandé dans la plupart des cas.
Paramètres régionaux et fuseau horaire
Les images de base par défaut peuvent avoir des paramètres régionaux incorrects. Configurez les paramètres régionaux et le fuseau horaire pour éviter les avertissements des outils de build, de Java, de Python et de Git.
initialize: - name: Configure locale and timezone run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq locales # Générer et définir la locale sudo sed -i 's/^# *en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen sudo locale-gen sudo update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 cat << 'LOCALE' | sudo tee /etc/profile.d/locale.sh > /dev/null export LANG="en_US.UTF-8" export LC_ALL="en_US.UTF-8" LOCALE # Définir le fuseau horaire sudo timedatectl set-timezone UTC 2>/dev/null || \ sudo ln -sfn /usr/share/zoneinfo/UTC /etc/localtime
Limites de ressources (ulimits)
Les builds Java, Gradle et Node.js atteignent fréquemment la limite par défaut de 1 024 fichiers ouverts. Augmentez-la pour éviter les build failures.
initialize: - name: Raise resource limits run: | cat << 'LIMITS' | sudo tee /etc/security/limits.d/99-devin.conf > /dev/null * soft nofile 65536 * hard nofile 65536 * soft nproc 65536 * hard nproc 65536 LIMITS # Définir aussi le maximum du noyau echo "fs.file-max = 65536" | sudo tee /etc/sysctl.d/99-devin-filemax.conf > /dev/null sudo sysctl -p /etc/sysctl.d/99-devin-filemax.conf 2>/dev/null || true
Remplacement du miroir APT
Dans les environnements en air gap ou restreints, remplacez les sources APT Ubuntu par défaut par un miroir interne.
direnv est intégré d’emblée au shell de Devin, donc les variables .envrc se chargent automatiquement. Aucun chargement manuel n’est nécessaire.
Pour les variables d’environnement sensibles (API keys, jetons, mots de passe de base de données), utilisez les secrets du dépôt plutôt que des fichiers .envrc. Les secrets du dépôt sont stockés de manière sécurisée et injectés au début de la session. Ils n’apparaissent jamais dans votre blueprint ni dans votre snapshot.
Sélection de la version de Node par dépôt
Utilisez nvm (préinstallé) pour changer de version de Node.js pour chaque dépôt via .nvmrc.
nvm use lit .nvmrc à la racine du dépôt. Assurez-vous que votre dépôt en contient un (p. ex. avec 20).
Authentification dans le navigateur (Playwright)
Devin fournit un navigateur Chrome avec un endpoint CDP sur localhost:29229pendant les sessions. Utilisez des scripts Playwright pour automatiser la connexion via le navigateur.
Le navigateur n’est disponible que pendant les sessions, pas dans les builds du snapshot. Installez Playwright dans initialize et conservez les scripts de connexion dans votre repo.
initialize: | pip install playwright playwright install chromiummaintenance: | npm installknowledge: - name: browser-auth contents: | This project requires browser authentication. Run the login script before interacting with the app: python scripts/login.py Devin's Chrome browser is accessible via CDP at: http://localhost:29229
Exemple de script de connexion (scripts/login.py) :
from playwright.sync_api import sync_playwrightimport oswith sync_playwright() as p: browser = p.chromium.connect_over_cdp("http://localhost:29229") context = browser.contexts[0] page = context.pages[0] if context.pages else context.new_page() page.goto("https://internal-tool.example.com/login") page.fill("#username", os.environ["TOOL_USERNAME"]) page.fill("#password", os.environ["TOOL_PASSWORD"]) page.click('button[type="submit"]') page.wait_for_url("**/dashboard")
Stockez les identifiants de connexion dans les secrets, pas dans le code source. Pour une authentification persistante, versionnez les scripts de connexion dans .agents/skills/ afin que Devin puisse se réauthentifier automatiquement.
Outils système personnalisés et PATH
Installez des packages système, des binaires personnalisés et configurez le PATH dans initialize.
Devin prend en charge l’exécution de GitHub Actions basées sur Node.js directement dans les blueprints. Cela est utile pour installer des versions spécifiques d’outils via les mêmes actions que celles utilisées par votre CI.
Des actions comme setup-node et setup-python modifient le PATH et les variables d’environnement. Les binaires installés par une action sont disponibles dans toutes les étapes suivantes et dans maintenance. Seules les
GitHub Actions basées sur Node.js sont prises en charge. Les actions composites et celles basées sur Docker ne le sont pas.
Vous n’avez pas besoin de GitHub Actions pour la configuration de base des outils. Des commandes shell directes (nvm install 20, curl ... | sh, apt-get install) fonctionnent tout aussi bien et sont souvent plus simples. Les GitHub Actions sont surtout utiles si vous voulez reproduire exactement votre configuration CI ou bénéficier de la praticité d’actions comme setup-java, qui gèrent plusieurs distributions.
Ces exemples montrent comment les configurations Enterprise et celles au niveau de l’org se combinent. En pratique, vous les répartiriez entre plusieurs périmètres. Elles sont regroupées ici à titre de référence.
Stack complète pour entreprise (Artifactory)
Un environnement d’entreprise complet : certificat d’autorité de certification d’entreprise, proxy, Java (Maven), Python (pip/uv), Node.js (npm) et Docker, le tout pointant vers une seule instance Artifactory.
Secrets requis
Réseau et confiance (échelle du compte) :
CORP_ROOT_CA_B64 — certificat d’autorité de certification d’entreprise encodé en Base64
CORP_HTTP_PROXY — URL du proxy HTTP
CORP_HTTPS_PROXY — URL du proxy HTTPS
CORP_NO_PROXY — hôtes à ne pas faire passer par le proxy
Identifiants du registre (échelle de l’organisation) :
ARTIFACTORY_USER — nom d’utilisateur Artifactory
ARTIFACTORY_TOKEN — jeton d’API Artifactory ou mot de passe
ARTIFACTORY_MAVEN_URL — URL du dépôt Maven (p. ex., https://artifactory.example.com/artifactory/maven-virtual)
ARTIFACTORY_PYPI_URL — URL du dépôt PyPI (p. ex., https://user:token@artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple)
ARTIFACTORY_NPM_URL — URL du dépôt npm (p. ex., https://artifactory.example.com/artifactory/api/npm/npm-virtual)
ARTIFACTORY_DOCKER_URL — URL du registre Docker (p. ex., artifactory.example.com)
Cela serait généralement réparti en trois périmètres :
À l’échelle du compte (initialize) : certificat et proxy
À l’échelle de l’organisation (initialize) : Installation des runtimes de langage
À l’échelle de l’organisation (maintenance) : Identifiants du registre (renouvelés à chaque session)
Dans cet exemple, tous les registres pointent vers la même instance Artifactory, mais utilisent des chemins d’URL différents. Chaque écosystème de packages a son propre format d’endpoint. Les URL Maven, PyPI, npm et Docker sont toutes différentes, même pour un même registre.
Plusieurs langages avec différents dépôts
Lorsque différents langages utilisent des registres privés différents (par ex. Maven via Nexus, npm via GitHub Packages, Python via Artifactory).
Secrets requis
NEXUS_MAVEN_URL — URL du dépôt Maven Nexus - NEXUS_USER — nom d’utilisateur Nexus - NEXUS_PASS — mot de passe Nexus - GITHUB_PACKAGES_TOKEN — jeton d’accès personnel GitHub avec le périmètre read:packages -
ARTIFACTORY_USER — nom d’utilisateur Artifactory - ARTIFACTORY_TOKEN — jeton d’API Artifactory - GIT_TOKEN — jeton d’accès personnel pour les modules Go privés
Dans un environnement totalement en air gap, Devin ne peut accéder à aucune URL publique. Tous les outils, environnements d’exécution et packages doivent provenir de miroirs internes.
Secrets requis
Certificats :
CORP_ROOT_CA_B64 — certificat d’autorité de certification de l’entreprise encodé en Base64
Accès au miroir :
APT_MIRROR_URL — URL du miroir APT Ubuntu interne
MIRROR_USER — nom d’utilisateur d’authentification au miroir
MIRROR_PASS — mot de passe d’authentification au miroir
JDK_TARBALL_URL — URL pour télécharger l’archive tar du JDK depuis le miroir interne
NODE_TARBALL_URL — URL pour télécharger l’archive tar de Node.js depuis le miroir interne
Registres de packages :
INTERNAL_MAVEN_URL — URL du registre Maven interne
Dans les environnements en air gap, tous les outils dont Devin a besoin (environnement d’exécution, outils CLI, etc.) doivent être disponibles sur vos miroirs internes. Les registres publics et les sites de téléchargement ne sont pas accessibles.
VPN + certificats + proxy + langages
Une configuration Enterprise complète combinant la connectivité VPN avec des certificats, un proxy et la prise en charge multilingue. Voici l’ordre des opérations recommandé.
Secrets nécessaires
VPN :
VPN_CONFIG_B64 — fichier de configuration OpenVPN encodé en Base64
Réseau & confiance :
CORP_ROOT_CA_B64 — certificat d’autorité de certification d’entreprise encodé en Base64
CORP_HTTP_PROXY — URL du proxy HTTP
CORP_HTTPS_PROXY — URL du proxy HTTPS
CORP_NO_PROXY — hôtes à contourner via le proxy
Identifiants du registre :
MAVEN_REGISTRY_URL — URL du registre Maven
NPM_REGISTRY_URL — URL du registre npm
PYPI_REGISTRY_HOST — nom d’hôte du registre PyPI
REGISTRY_USER — nom d’utilisateur du registre (pour Maven et pip)
REGISTRY_PASS — mot de passe du registre (pour Maven et pip)
REGISTRY_TOKEN — jeton d’authentification npm
initialize: # 1. VPN — doit être configuré en premier pour que les ressources internes soient accessibles - name: Establish VPN connection run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openvpn sudo mkdir -p /etc/openvpn/client echo "$VPN_CONFIG_B64" | base64 -d \ | sudo tee /etc/openvpn/client/corp.conf > /dev/null sudo systemctl daemon-reload sudo systemctl enable --now openvpn-client@corp for i in $(seq 1 30); do if ip link show tun0 >/dev/null 2>&1; then break; fi sleep 1 done # 2. DNS — résolution des noms d'hôtes internes - name: Configure DNS run: | sudo mkdir -p /etc/systemd/resolved.conf.d cat << 'DNS' | sudo tee /etc/systemd/resolved.conf.d/corp.conf > /dev/null [Resolve] DNS=10.0.0.53 Domains=corp.internal DNS sudo systemctl restart systemd-resolved || true # 3. Certificats — approuver les autorités de certification internes - name: Install CA certificate run: | echo "$CORP_ROOT_CA_B64" | base64 -d \ | sudo tee /usr/local/share/ca-certificates/corp-root-ca.crt > /dev/null sudo update-ca-certificates echo 'export NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/corp-root-ca.crt' \ | sudo tee /etc/profile.d/node-ca.sh > /dev/null # 4. Proxy — acheminer le trafic via le proxy d'entreprise - name: Configure proxy run: | cat << 'PROXY' | sudo tee /etc/profile.d/proxy.sh > /dev/null export http_proxy="$CORP_HTTP_PROXY" export https_proxy="$CORP_HTTPS_PROXY" export no_proxy="$CORP_NO_PROXY" export HTTP_PROXY="$CORP_HTTP_PROXY" export HTTPS_PROXY="$CORP_HTTPS_PROXY" export NO_PROXY="$CORP_NO_PROXY" PROXY source /etc/profile.d/proxy.sh # 5. Environnements d'exécution - name: Install JDK 17 run: | sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-17-jdk-headless echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' \ | sudo tee /etc/profile.d/java.sh > /dev/null - name: Install Node.js tooling run: npm install -g pnpm - name: Install uv run: curl -LsSf https://astral.sh/uv/install.sh | shmaintenance: - name: Configure git proxy run: | git config --global http.proxy "$CORP_HTTP_PROXY" git config --global https.proxy "$CORP_HTTPS_PROXY" - name: Configure Maven run: | mkdir -p ~/.m2 cat > ~/.m2/settings.xml << EOF <settings> <mirrors> <mirror> <id>corp</id> <mirrorOf>*</mirrorOf> <url>$MAVEN_REGISTRY_URL</url> </mirror> </mirrors> <servers> <server> <id>corp</id> <username>$REGISTRY_USER</username> <password>$REGISTRY_PASS</password> </server> </servers> </settings> EOF - name: Configure npm run: | npm config set registry "$NPM_REGISTRY_URL" NPM_HOST=$(echo "$NPM_REGISTRY_URL" | sed 's|https\?://||;s|/.*||') npm config set "//${NPM_HOST}/:_authToken" "$REGISTRY_TOKEN" - name: Configure pip/uv run: | mkdir -p ~/.config/pip cat > ~/.config/pip/pip.conf << EOF [global] index-url = https://$REGISTRY_USER:$REGISTRY_PASS@${PYPI_REGISTRY_HOST}/simple EOF echo "export UV_INDEX_URL=https://$REGISTRY_USER:$REGISTRY_PASS@${PYPI_REGISTRY_HOST}/simple" \ | sudo tee /etc/profile.d/uv-registry.sh > /dev/null
L’ordre des étapes initialize est important. Le VPN doit venir en premier (pour que les hôtes internes soient accessibles), puis le DNS (pour que la résolution des noms fonctionne), puis les certificats (pour que HTTPS fonctionne), puis le proxy (pour que le trafic soit correctement acheminé), et enfin les environnements d’exécution (qui peuvent télécharger depuis des miroirs internes).
Testez d’abord les commandes dans une session. Exécutez-les manuellement dans une session Devin avant de les ajouter à votre blueprint. C’est plus rapide que d’attendre un cycle de build complet.
Utilisez initialize pour les outils à installer une seule fois, et maintenance pour les dépendances. Tout ce qui prend plusieurs minutes à installer (compilateurs, gros binaires, outils globaux) doit aller dans initialize. Les commandes de dépendances rapides (npm install, uv sync) vont dans maintenance.
Veillez à ce que les commandes maintenance restent rapides. Visez moins de 2 minutes. Elles s’exécutent au début de chaque session.
Utilisez $ENVRC pour les variables d’environnement. N’écrivez pas dans .bashrc ou .profile. $ENVRC est le mécanisme pris en charge pour définir des variables entre les étapes et les sessions.
Nommez vos étapes. La syntaxe développée avec des champs name permet d’identifier beaucoup plus facilement les échecs dans les journaux de build.
Utilisez des subshells pour les monorepos.(cd packages/foo && npm install) s’exécute dans un subshell afin que les étapes suivantes ne soient pas affectées par le changement de répertoire.
Utilisez npm install, pas npm ci.npm ci supprime node_modules et réinstalle tout depuis zéro à chaque session, ce qui est trop lent pour maintenance.
Utilisez les secrets du dépôt pour les valeurs sensibles. Configurez-les dans Settings > Secrets avec le périmètre du dépôt plutôt que de les coder en dur dans les blueprints.