Passer au contenu principal
Cette page fournit des exemples autonomes de environment.yaml pour des scénarios courants. Chaque exemple couvre un seul aspect — combinez-les pour créer votre configuration complète. Pour une introduction à la syntaxe et aux concepts de environment.yaml, consultez Configuration de l’environnement. Pour plus de détails sur la syntaxe, consultez la Référence YAML.
Secrets : Les exemples font référence aux secrets via $SECRET_NAME. Configurez-les dans Settings → Secrets avant d’utiliser un exemple. Chaque exemple inclut une section réductible “Secrets requis” qui indique précisément quels secrets configurer et les valeurs attendues. N’intégrez jamais d’identifiants en dur dans votre environment.yaml.

Référence rapide : configurations les plus courantes

Les configurations les plus utilisées sont regroupées ici. Pour la liste complète, consultez les sections ci-dessous.
initialize: |
  npm install -g pnpm

maintenance: |
  pnpm install

knowledge:
  - 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.
initialize:
  - name: Installer uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh

maintenance:
  - name: Synchroniser les dépendances
    run: uv sync

knowledge:
  - name: lint
    contents: |
      Exécutez `uv run ruff check .` pour lancer le linting.
  - name: test
    contents: |
      Exécutez `uv run pytest` pour lancer la suite complète.
initialize:
  - name: Installer pnpm
    run: npm install -g pnpm
  - name: Installer uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh

maintenance:
  - name: Dépendances frontend
    run: (cd frontend && pnpm install)
  - name: Dépendances backend
    run: (cd backend && uv sync)

knowledge:
  - name: structure
    contents: |
      - `frontend/` — application React (pnpm)
      - `backend/` — API Python (uv)
  - name: test
    contents: |
      Frontend : cd frontend && pnpm test
      Backend : cd backend && uv run pytest
initialize: |
  npm install -g pnpm

maintenance: |
  pnpm install

knowledge:
  - name: structure
    contents: |
      Monorepo géré avec les workspaces pnpm.
      - `packages/web` — frontend Next.js
      - `packages/api` — backend Express.js
      - `packages/shared` — utilitaires partagés
  - name: test
    contents: |
      Exécutez `pnpm test` depuis la racine pour tous les packages.
      Exécutez `pnpm --filter web test` pour un package spécifique.

Comment les couches fonctionnent

Les configurations d’environnement sont appliquées par couches. Chaque couche s’appuie sur la précédente :
1

échelle du compte (Enterprise)

Certificats, proxy, DNS, VPN, signature de commit, paramètres régionaux, limites de ressources, identité git, miroirs APT. S’applique à toutes les orgs et tous les dépôts.
2

échelle de l’organisation

environnement d’exécution de langage, configuration du registre du gestionnaire de packages, registre de conteneurs, outils partagés. S’applique à tous les dépôts au sein de l’org.
3

Spécifique au dépôt

Commandes de build, installation des dépendances, commandes de test/lint, notes spécifiques au projet pour Devin. S’applique à un seul dépôt.
Ce qui est défini à l’échelle du compte s’exécute d’abord, puis ce qui est défini à l’échelle de l’organisation, puis ce qui est spécifique au dépôt. Configurez chaque exemple au périmètre approprié dans Settings.

Référence des modules

Utilisez ce tableau pour trouver l’exemple adapté à vos besoins. Chaque module est indépendant — combinez-les librement.
ModuleCoucheSection
Certificats d’autorité de certificationEnterpriseCertificat d’autorité de certification d’entreprise
Plusieurs certificats d’autorité de certificationEnterprisePlusieurs certificats d’autorité de certification
Proxy HTTP/HTTPSEnterpriseProxy HTTP/HTTPS
Proxy authentifiéEnterpriseProxy authentifié
Certificat d’autorité de certification + proxyEnterpriseCertificat d’autorité de certification + proxy (combiné)
VPN (OpenVPN / WireGuard)EnterpriseConnexion VPN
DNS personnaliséEnterpriseRésolution DNS personnalisée
Signature GPG des commitsEnterpriseSignature GPG des commits
Identité Git + clés SSHEnterpriseIdentité Git et clés SSH
Packages systèmeEnterpriseInstaller des packages système
Variables d’environnementEnterpriseVariables d’environnement personnalisées
Paramètres régionaux et fuseau horaireEnterpriseParamètres régionaux et fuseau horaire
Limites de ressourcesEnterpriseLimites de ressources (ulimits)
Miroir APTEnterpriseRemplacement du miroir APT
Java + MavenOrgJava + Maven avec un registre privé
Java + GradleOrgJava + Gradle avec un registre privé
Python + pip/uvOrgPython + pip/uv avec un registre privé
Python + PoetryOrgPython + Poetry avec un registre privé
Node.js + npm (scoped)OrgNode.js + npm avec un registre privé scoped
Node.js + npm (miroir complet)OrgNode.js + npm avec un miroir complet de registre privé
Node.js + pnpmOrgNode.js + pnpm avec un registre privé
Node.js + YarnOrgNode.js + Yarn avec un registre privé
GoOrgGo avec un proxy de modules privé
.NET + NuGetOrg.NET + NuGet avec un flux privé
DockerOrgDocker avec un registre de conteneurs privé
Rust + CargoOrgRust + Cargo avec un registre privé
Ruby + BundlerOrgRuby + Bundler avec un serveur de gems privé
PHP + ComposerOrgPHP + Composer avec un registre privé
AWS CodeArtifactOrgActualisation du token AWS CodeArtifact
Projet Node.jsRepoProjet Node.js standard
Projet PythonRepoProjet Python standard
Projet JavaRepoProjet Java standard
Projet GoRepoProjet Go standard
Projet RustRepoProjet Rust standard
MonorepoRepoMonorepo avec plusieurs services
Monorepo multi-JDKRepoMonorepo avec plusieurs versions de JDK
Entrées KnowledgeRepoEntrées Knowledge enrichies
Hooks pre-commitRepoHooks pre-commit

Exemples Enterprise / à l’échelle du compte

Ces exemples configurent une infrastructure au niveau de la machine qui s’applique à toutes les orgs et à tous les dépôts. Définissez-les dans Enterprise Settings (pour l’échelle du compte) ou dans Settings > Environment > Configuration à l’échelle de l’organisation (pour l’échelle de l’organisation).

Certificat d’autorité de certification d’entreprise

Votre organisation utilise une autorité de certification privée pour ses services internes. Devin a besoin du certificat racine pour accéder aux registres et aux outils internes via HTTPS.
  • CORP_ROOT_CA_B64 — Certificat PEM encodé en base64 provenant de votre AC d’entreprise. Générez-le avec : cat corp-root-ca.crt | base64 -w0
initialize:
  - name: Install corporate 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

      # Permettre à Node.js de faire confiance à l'AC d'entreprise
      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

Plusieurs certificats d’autorité de certification

Certaines organisations ont des autorités de certification distinctes pour différents services internes (par exemple, une pour le registre d’artefacts, une autre pour un serveur Git interne).
  • CA_CERT_REGISTRY_B64 — Certificat PEM encodé en Base64 pour l’autorité de certification du registre d’artefacts
  • CA_CERT_GIT_B64 — Certificat PEM encodé en Base64 pour l’autorité de certification du serveur Git
initialize:
  - name: Install corporate CA certificates
    run: |
      # Decode and install each certificate
      echo "$CA_CERT_REGISTRY_B64" | base64 -d \
        | sudo tee /usr/local/share/ca-certificates/registry-ca.crt > /dev/null
      echo "$CA_CERT_GIT_B64" | base64 -d \
        | sudo tee /usr/local/share/ca-certificates/git-ca.crt > /dev/null

      sudo update-ca-certificates

      # Node.js: combine certs into a single bundle
      cat /usr/local/share/ca-certificates/registry-ca.crt \
          /usr/local/share/ca-certificates/git-ca.crt \
        > /tmp/corp-ca-bundle.crt
      echo "export NODE_EXTRA_CA_CERTS=/tmp/corp-ca-bundle.crt" \
        | sudo tee /etc/profile.d/node-ca.sh > /dev/null

Proxy HTTP/HTTPS

Votre organisation fait transiter le trafic sortant par un proxy d’entreprise.
  • CORP_HTTP_PROXY — URL du proxy HTTP (par exemple, http://proxy.corp.internal:8080)
  • CORP_HTTPS_PROXY — URL du proxy HTTPS (par exemple, http://proxy.corp.internal:8080)
  • CORP_NO_PROXY — Hôtes séparés par des virgules qui doivent ignorer le proxy (par exemple, localhost,127.0.0.1,.corp.internal,10.0.0.0/8)
initialize:
  - name: Configure system-wide HTTP/HTTPS 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

maintenance:
  - name: Configure git proxy
    run: |
      git config --global http.proxy "$CORP_HTTP_PROXY"
      git config --global https.proxy "$CORP_HTTPS_PROXY"
Définissez CORP_NO_PROXY sur une liste d’hôtes, séparés par des virgules, qui doivent ignorer le proxy, par exemple localhost,127.0.0.1,.corp.internal,10.0.0.0/8.

Proxy avec authentification

Si votre proxy nécessite un nom d’utilisateur et un mot de passe, incluez les identifiants dans l’URL du proxy.
  • PROXY_USER — Nom d’utilisateur pour l’authentification du proxy
  • PROXY_PASS — Mot de passe pour l’authentification du proxy
  • PROXY_HOST — Nom d’hôte du proxy (par ex. proxy.corp.internal)
  • PROXY_PORT — Port du proxy (par ex. 8080)
  • CORP_NO_PROXY — Hôtes à exclure du proxy, séparés par des virgules
initialize:
  - name: Configure authenticated HTTP/HTTPS proxy
    run: |
      cat << 'PROXY' | sudo tee /etc/profile.d/proxy.sh > /dev/null
      export http_proxy="http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT"
      export https_proxy="http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT"
      export no_proxy="$CORP_NO_PROXY"
      export HTTP_PROXY="$http_proxy"
      export HTTPS_PROXY="$https_proxy"
      export NO_PROXY="$CORP_NO_PROXY"
      PROXY
      source /etc/profile.d/proxy.sh

maintenance:
  - name: Configure git proxy
    run: |
      git config --global http.proxy "http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT"
      git config --global https.proxy "http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST:$PROXY_PORT"

Certificat d’AC + proxy (combinés)

La configuration de base la plus courante en entreprise consiste à installer un certificat d’AC d’entreprise et à configurer un proxy à l’échelle du système.
  • CORP_ROOT_CA_B64 — Certificat PEM encodé en Base64 provenant de votre AC d’entreprise
  • CORP_HTTP_PROXY — URL du proxy HTTP
  • CORP_HTTPS_PROXY — URL du proxy HTTPS
  • CORP_NO_PROXY — Hôtes séparés par des virgules pour contourner le proxy
initialize:
  - name: Install corporate 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

  - name: Configure system-wide 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

maintenance:
  - name: Configure git proxy
    run: |
      git config --global http.proxy "$CORP_HTTP_PROXY"
      git config --global https.proxy "$CORP_HTTPS_PROXY"

Connexion VPN

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.
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 VPN, si votre VPN nécessite une authentification par nom d’utilisateur/mot de passe
  • VPN_AUTH_PASS (facultatif) — Mot de passe VPN
WireGuard :
  • WG_CONFIG_B64 — Fichier de configuration WireGuard encodé en Base64. Générez-le avec : cat wg0.conf | base64 -w0
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 nécessite 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
Pour plus de détails sur la configuration du VPN, consultez Configuration VPN.

Résolution DNS personnalisée

Vos services internes utilisent des noms DNS privés qui ne peuvent pas être résolus par le DNS public.
initialize:
  - name: Configure custom DNS resolution
    run: |
      # Ajouter les noms d'hôtes internes
      cat << 'HOSTS' | sudo tee -a /etc/hosts > /dev/null
      10.0.1.50  nexus.corp.internal
      10.0.1.51  git.corp.internal
      10.0.1.52  artifactory.corp.internal
      HOSTS

      # Configurer optionnellement des serveurs de noms personnalisés
      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 10.0.0.54
      Domains=corp.internal
      DNS
      sudo systemctl restart systemd-resolved || true

Signature des commits avec GPG

Votre organisation exige que tous les commits Git soient signés.
  • GPG_PRIVATE_KEY_B64 — Clé GPG privée encodée en Base64. Générez-la avec : gpg --export-secret-keys <key-id> | base64 -w0
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/null

      # Préconfigurer git pour signer les commits (clé importée lors de la maintenance)
      git config --global commit.gpgsign true
      git config --global tag.gpgsign true

maintenance:
  - name: Import GPG signing key
    run: |
      echo "$GPG_PRIVATE_KEY_B64" | base64 -d | gpg --batch --import

      # Définir l'ID de la clé de signature
      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"

Identité Git et clés SSH

Configurez l’identité Git de l’utilisateur et les clés SSH pour accéder à des dépôts privés via SSH.
  • GIT_USER_NAME — Nom de l’auteur Git (p. ex., Devin AI)
  • GIT_USER_EMAIL — Adresse e-mail de l’auteur Git (p. ex., devin@company.com)
  • 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 — Hôtes connus encodés 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 pour les alias d’hôte personnalisés
initialize:
  - name: Prepare SSH directory and git identity
    run: |
      # Définir l'identité git
      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 ~/.ssh

      # Activer git-lfs si nécessaire
      # git lfs install

maintenance:
  - name: Install SSH keys
    run: |
      # Installer la clé privée SSH (en maintenance pour qu'elle soit rechargée à chaque session)
      echo "$SSH_PRIVATE_KEY_B64" | base64 -d > ~/.ssh/id_ed25519
      chmod 600 ~/.ssh/id_ed25519

      # Ajouter les hôtes connus pour 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 du fichier known_hosts pour votre serveur Git avec ssh-keyscan git.corp.internal | base64 -w0.

Installer des packages système

Votre projet nécessite des packages système qui ne figurent pas dans l’image Devin par défaut (par ex., des bibliothèques natives pour le traitement d’images ou la génération de PDF).
initialize:
  - name: Install system packages
    run: |
      sudo apt-get update -qq
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
        libpq-dev \
        libmagickwand-dev \
        poppler-utils \
        ffmpeg

Variables d’environnement personnalisées

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 et pour la session Devin (comme avec le $GITHUB_ENV de GitHub Actions).
initialize:
  - name: Set custom environment variables
    run: |
      echo "CORPORATE_ENV=production" >> $ENVRC
      echo "DEFAULT_REGION=us-east-1" >> $ENVRC
      echo "MAX_RETRIES=3" >> $ENVRC
Vous pouvez également définir des variables d’environnement dans des scripts /etc/profile.d/ afin de les rendre disponibles à l’échelle du système :
cat << 'ENVVARS' | sudo tee /etc/profile.d/custom-env.sh > /dev/null
export CORPORATE_ENV=production
export DEFAULT_REGION=us-east-1
ENVVARS
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 mal configurés. Configurez les paramètres régionaux et le fuseau horaire afin d’é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 se heurtent souvent à la limite par défaut de 1 024 fichiers ouverts. Augmentez-la pour éviter les échecs de build.
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 également 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 cloisonnés ou restreints, remplacez les dépôts APT Ubuntu par défaut par un miroir interne.
  • APT_MIRROR_URL — URL de votre miroir APT interne (par ex. https://artifactory.example.com/artifactory/ubuntu-remote)
initialize:
  - name: Replace APT sources with internal mirror
    run: |
      # Sauvegarder les sources originales
      sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

      # Remplacer tous les miroirs Ubuntu par votre miroir interne
      sudo sed -i "s|http://archive.ubuntu.com/ubuntu|$APT_MIRROR_URL|g" /etc/apt/sources.list
      sudo sed -i "s|http://security.ubuntu.com/ubuntu|$APT_MIRROR_URL|g" /etc/apt/sources.list

      # Désactiver les sources tierces inaccessibles
      # sudo mv /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/disabled/ 2>/dev/null || true

      sudo apt-get update -qq
Schémas d’URL courants pour les miroirs APT :
  • Artifactory : https://artifactory.example.com/artifactory/ubuntu-remote
  • Nexus : https://nexus.example.com/repository/ubuntu-proxy

Exemples à l’échelle de l’organisation

Ces exemples installent des environnements d’exécution de langage et configurent les gestionnaires de package pour utiliser des registres privés. Définissez-les dans Settings > Environment > Configuration à l’échelle de l’organisation.
Si votre registre privé utilise un certificat d’autorité de certification d’entreprise, assurez-vous d’abord que le certificat d’autorité de certification est installé au niveau Enterprise. La configuration au niveau de l’organisation ci-dessous suppose que la confiance HTTPS est déjà établie.
La configuration des identifiants doit se faire dans maintenance, et non 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 actualisés à chaque session. Le fichier de secrets est supprimé avant l’enregistrement de l’image machine, de sorte que les fichiers de configuration écrits pendant initialize n’auront pas d’identifiants valides au démarrage des sessions.

Java + Maven avec un dépôt privé

Installez le JDK et configurez Maven pour faire transiter toute la résolution des dépendances via votre dépôt privé (par exemple, Artifactory ou Nexus).
Le JDK 17 est préinstallé sur l’image de base de Devin. Ignorez l’étape d’installation ci-dessous si l’OpenJDK 17 par défaut suffit — vous n’avez besoin que de l’installation de Maven et de la configuration du registre.
  • MAVEN_REGISTRY_URL — URL de votre registre Maven (par exemple, 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
initialize:
  - name: Install JDK 17
    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: Install Maven
    run: |
      MAVEN_VERSION=3.9.9
      curl -fsSL "https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz" \
        | sudo tar -xz -C /opt
      sudo ln -sf /opt/apache-maven-${MAVEN_VERSION}/bin/mvn /usr/local/bin/mvn

maintenance:
  - name: Configure Maven for private registry
    run: |
      mkdir -p ~/.m2
      cat > ~/.m2/settings.xml << EOF
      <settings>
        <mirrors>
          <mirror>
            <id>private-registry</id>
            <mirrorOf>*</mirrorOf>
            <url>$MAVEN_REGISTRY_URL</url>
          </mirror>
        </mirrors>
        <servers>
          <server>
            <id>private-registry</id>
            <username>$REGISTRY_USER</username>
            <password>$REGISTRY_PASS</password>
          </server>
        </servers>
      </settings>
      EOF
Formats d’URL courants pour les registres Maven :
  • Artifactory: https://artifactory.example.com/artifactory/maven-virtual
  • Nexus: https://nexus.example.com/repository/maven-public
  • Azure Artifacts: https://pkgs.dev.azure.com/org/project/_packaging/feed/maven/v1
  • GitHub Packages: https://maven.pkg.github.com
  • GitLab: https://gitlab.example.com/api/v4/groups/<group-id>/-/packages/maven
  • AWS CodeArtifact: https://<domain>.d.codeartifact.<region>.amazonaws.com/maven/<repo>

Java + Gradle avec un dépôt privé

Installez le JDK et configurez Gradle pour résoudre toutes les dépendances via votre dépôt privé.
JDK 17 est préinstallé sur l’image de base de Devin. Ignorez l’étape d’installation du JDK si la configuration par défaut vous convient.
  • 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
initialize:
  - name: Install JDK 17
    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: Install Gradle
    run: |
      GRADLE_VERSION=8.12
      curl -fsSL "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" \
        -o /tmp/gradle.zip
      sudo unzip -qo /tmp/gradle.zip -d /opt
      sudo ln -sf /opt/gradle-${GRADLE_VERSION}/bin/gradle /usr/local/bin/gradle
      rm /tmp/gradle.zip

maintenance:
  - name: Configure Gradle for private registry
    run: |
      mkdir -p ~/.gradle
      cat > ~/.gradle/init.gradle << EOF
      allprojects {
          repositories {
              maven {
                  url "$GRADLE_REGISTRY_URL"
                  credentials {
                      username = "$REGISTRY_USER"
                      password = "$REGISTRY_PASS"
                  }
                  allowInsecureProtocol = false
              }
          }
      }
      EOF

Python + pip/uv avec un registre privé

Configurez pip et uv pour récupérer les paquets depuis votre registre PyPI privé (par ex. Nexus, Artifactory).
  • PYPI_REGISTRY_HOST — Nom d’hôte de votre registre PyPI (par ex. artifactory.example.com/artifactory/api/pypi/pypi-virtual)
  • REGISTRY_USER — Nom d’utilisateur du registre
  • REGISTRY_PASS — Mot de passe du registre ou jeton d’API
initialize:
  - name: Install uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh

maintenance:
  - name: Configure pip for private registry
    run: |
      mkdir -p ~/.config/pip
      cat > ~/.config/pip/pip.conf << EOF
      [global]
      index-url = https://$REGISTRY_USER:$REGISTRY_PASS@${PYPI_REGISTRY_HOST}/simple
      trusted-host = ${PYPI_REGISTRY_HOST}
      EOF

  - name: Configure uv for private registry
    run: |
      # uv respecte pip.conf, mais vous pouvez aussi le définir explicitement
      echo "export UV_INDEX_URL=https://$REGISTRY_USER:$REGISTRY_PASS@${PYPI_REGISTRY_HOST}/simple" \
        | sudo tee /etc/profile.d/uv-registry.sh > /dev/null
Schémas d’URL courants pour les registres PyPI :
  • Artifactory: https://artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple
  • Nexus: https://nexus.example.com/repository/pypi-group/simple
  • Azure Artifacts: https://pkgs.dev.azure.com/org/project/_packaging/feed/pypi/simple/
  • GitLab: https://gitlab.example.com/api/v4/groups/<group-id>/-/packages/pypi/simple
  • AWS CodeArtifact: https://<domain>.d.codeartifact.<region>.amazonaws.com/pypi/<repo>/simple

Python + Poetry avec un registre privé

Configurez Poetry pour récupérer des packages à partir d’un registre PyPI privé.
  • PYPI_REGISTRY_HOST — Nom d’hôte de votre registre PyPI
  • REGISTRY_USER — Nom d’utilisateur du registre
  • REGISTRY_PASS — Mot de passe du registre ou jeton d’API
initialize:
  - name: Install Poetry
    run: curl -sSL https://install.python-poetry.org | python3 -

maintenance:
  - name: Configure Poetry for private registry
    run: |
      poetry config repositories.private "https://${PYPI_REGISTRY_HOST}/simple"
      poetry config http-basic.private "$REGISTRY_USER" "$REGISTRY_PASS"

      # Définir facultativement le registre privé comme source par défaut
      # poetry source add --priority=primary private "https://${PYPI_REGISTRY_HOST}/simple"

Node.js + npm avec un registre privé associé à un périmètre

Configurez npm pour récupérer les packages d’un périmètre donné (par ex., @myorg/*) depuis un registre privé comme GitHub Packages, tandis que les packages publics continuent de provenir du registre npm par défaut.
  • 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 périmètre npm. Voici des URL courantes de registres privés :
  • GitHub Packages: https://npm.pkg.github.com
  • Artifactory: https://artifactory.example.com/artifactory/api/npm/npm-virtual
  • Nexus: https://nexus.example.com/repository/npm-group
  • GitLab: https://gitlab.example.com/api/v4/packages/npm
  • AWS CodeArtifact: https://<domain>.d.codeartifact.<region>.amazonaws.com/npm/<repo>

Node.js + npm avec un miroir complet de registre privé

Faites passer tous les packages npm par votre registre privé (pas seulement les packages avec périmètre).
  • 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: Configurer npm pour utiliser un registre privé
    run: |
      npm config set registry $NPM_REGISTRY_URL
      npm config set //${NPM_REGISTRY_HOST}/:_authToken $REGISTRY_TOKEN
      npm config set strict-ssl true

Node.js + pnpm avec un registre privé

Configurez pnpm pour récupérer des packages à partir d’un registre privé.
pnpm est préinstallé sur l’image de base de Devin. Vous pouvez ignorer l’étape d’installation et uniquement configurer le registre.
  • 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 pnpm

maintenance:
  - name: Configure pnpm for private registry
    run: |
      pnpm config set registry $NPM_REGISTRY_URL
      pnpm config set //${NPM_REGISTRY_HOST}/:_authToken $REGISTRY_TOKEN

Node.js + Yarn avec un registre privé

Configurez Yarn (Classic v1 ou Berry v2+) pour récupérer des packages à partir d’un registre privé.
Yarn Classic (v1) est préinstallé sur l’image de base de Devin. Passez l’étape d’installation si vous n’avez besoin que de v1.
  • NPM_REGISTRY_URL — URL complète de votre registre npm/Yarn
  • REGISTRY_TOKEN — Jeton d’authentification pour le registre (Berry uniquement)
initialize:
  - name: Install Yarn Classic
    run: npm install -g yarn

maintenance:
  - name: Configure Yarn for private registry
    run: |
      yarn config set registry "$NPM_REGISTRY_URL"
      # Pour les packages avec scope :
      # yarn config set @myorg:registry "https://npm.pkg.github.com"

Utiliser un proxy de modules privé avec Go

Installez Go et configurez-le pour récupérer les modules via un proxy de modules privé (par ex. Athens, Artifactory ou un endpoint GOPROXY).
  • 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/*"
      GOENV

maintenance:
  - name: Authenticate Go private modules
    run: |
      git config --global url."https://$GIT_TOKEN@github.com/myorg/".insteadOf "https://github.com/myorg/"
Schémas d’URL de proxy Go courants :
  • Artifactory: https://artifactory.example.com/artifactory/go-virtual
  • Nexus: https://nexus.example.com/repository/go-proxy
  • Athens: https://athens.corp.internal

.NET + NuGet avec une source privée

Installez le SDK .NET et configurez NuGet pour récupérer les packages depuis une source privée (par ex., Azure Artifacts, Artifactory).
  • NUGET_FEED_URL — URL de votre flux NuGet (par ex., https://pkgs.dev.azure.com/org/project/_packaging/feed/nuget/v3/index.json)
  • REGISTRY_USER — Nom d’utilisateur du registre
  • REGISTRY_PASS — Mot de passe du registre ou jeton d’API
initialize:
  - name: Install .NET SDK
    run: |
      curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
      chmod +x /tmp/dotnet-install.sh
      sudo /tmp/dotnet-install.sh --channel 8.0 --install-dir /usr/local/dotnet
      echo 'export DOTNET_ROOT=/usr/local/dotnet' \
        | sudo tee /etc/profile.d/dotnet.sh > /dev/null
      echo 'export PATH="$DOTNET_ROOT:$DOTNET_ROOT/tools:$PATH"' \
        | sudo tee -a /etc/profile.d/dotnet.sh > /dev/null
      rm /tmp/dotnet-install.sh

maintenance:
  - name: Configure NuGet for private feed
    run: |
      dotnet nuget add source "$NUGET_FEED_URL" \
        --name private-feed \
        --username "$REGISTRY_USER" \
        --password "$REGISTRY_PASS" \
        --store-password-in-clear-text

      # Désactiver éventuellement la source nuget.org par défaut
      # dotnet nuget disable source nuget.org
URL de flux NuGet courantes :
  • Azure Artifacts: https://pkgs.dev.azure.com/org/project/_packaging/feed/nuget/v3/index.json
  • Artifactory: https://artifactory.example.com/artifactory/api/nuget/v3/nuget-virtual
  • GitHub Packages: https://nuget.pkg.github.com/myorg/index.json
  • Nexus: https://nexus.example.com/repository/nuget-hosted/index.json

Docker avec un registre de conteneurs privé

Configurez Docker pour s’authentifier auprès d’un registre privé de conteneurs.
  • DOCKER_MIRROR_URL (facultatif) — URL de votre miroir Docker Hub (par ex., https://mirror.corp.internal)
  • DOCKER_REGISTRY_URL — URL de votre registre de conteneurs privé (par ex., 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/docker

maintenance:
  - 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
URL courantes des registres de conteneurs :
  • Amazon ECR: <account-id>.dkr.ecr.<region>.amazonaws.com
  • Azure Container Registry: <name>.azurecr.io
  • Google Artifact Registry: <region>-docker.pkg.dev
  • GitHub Container Registry: ghcr.io
  • GitLab Container Registry: registry.gitlab.example.com
  • Nexus: https://nexus.example.com:8443
  • JFrog: <name>.jfrog.io

Rust + Cargo avec un registre privé

Installez Rust et configurez Cargo pour récupérer des crates depuis un registre privé.
Rust (via rustup) et Cargo sont préinstallés sur l’image de base de Devin. Ignorez l’étape d’installation si la toolchain stable par défaut est suffisante — vous n’avez besoin que de la configuration du registre.
  • CARGO_REGISTRY_INDEX — URL de l’index du registre privé (par ex., sparse+https://cargo.corp.internal/api/v1/crates/)
  • CARGO_REGISTRY_TOKEN — Jeton d’authentification pour le registre privé
initialize:
  - name: Install Rust
    run: |
      curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
        | sh -s -- -y --default-toolchain stable
      echo 'source "$HOME/.cargo/env"' \
        | sudo tee /etc/profile.d/rust.sh > /dev/null

maintenance:
  - name: Configure Cargo for private registry
    run: |
      mkdir -p ~/.cargo
      cat > ~/.cargo/config.toml << EOF
      [registries.private]
      index = "$CARGO_REGISTRY_INDEX"
      token = "$CARGO_REGISTRY_TOKEN"

      [source.crates-io]
      replace-with = "private"

      [source.private]
      registry = "$CARGO_REGISTRY_INDEX"
      EOF
Si vous devez seulement ajouter un registre privé sans remplacer crates.io, supprimez les sections [source.crates-io] et [source.private] et utilisez cargo install --registry private ou [dependencies] my-crate = { version = "1.0", registry = "private" } dans Cargo.toml.

Ruby + Bundler avec un serveur privé de gems

Installez Ruby et configurez Bundler pour récupérer les gems depuis un serveur privé de gems.
  • GEM_SERVER_URL — URL de votre serveur privé de gems (par 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-full

maintenance:
  - 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 des serveurs de gems :
  • Artifactory: https://artifactory.example.com/artifactory/api/gems/gems-virtual
  • Nexus: https://nexus.example.com/repository/rubygems-proxy
  • Gemfury: https://gem.fury.io/<org>

Renouvellement du jeton AWS CodeArtifact

Les jetons AWS CodeArtifact expirent au bout de 12 heures. Utilisez maintenance pour renouveler 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. Seuls le renouvellement du jeton et la configuration du registre sont nécessaires.
  • AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY — identifiants IAM disposant des 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 (par ex., us-east-1)
  • CA_NPM_REPO, CA_PYPI_REPO, CA_MAVEN_REPO — Noms des dépôts pour chaque écosystème
maintenance:
  - name: Refresh CodeArtifact auth token
    run: |
      # Obtenir un token récent (valide pendant 12 heures)
      export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \
        --domain $CA_DOMAIN \
        --domain-owner $CA_DOMAIN_OWNER \
        --region $CA_REGION \
        --query authorizationToken \
        --output text)

      CA_ENDPOINT="https://${CA_DOMAIN}-${CA_DOMAIN_OWNER}.d.codeartifact.${CA_REGION}.amazonaws.com"

      # Configurer npm
      npm config set registry "${CA_ENDPOINT}/npm/${CA_NPM_REPO}/"
      npm config set "//${CA_DOMAIN}-${CA_DOMAIN_OWNER}.d.codeartifact.${CA_REGION}.amazonaws.com/npm/${CA_NPM_REPO}/:_authToken" "$CODEARTIFACT_AUTH_TOKEN"

      # Configurer pip
      mkdir -p ~/.config/pip
      cat > ~/.config/pip/pip.conf << EOF
      [global]
      index-url = https://aws:${CODEARTIFACT_AUTH_TOKEN}@${CA_DOMAIN}-${CA_DOMAIN_OWNER}.d.codeartifact.${CA_REGION}.amazonaws.com/pypi/${CA_PYPI_REPO}/simple/
      EOF

      # Configurer Maven (facultatif)
      mkdir -p ~/.m2
      cat > ~/.m2/settings.xml << EOF
      <settings>
        <servers>
          <server>
            <id>codeartifact</id>
            <username>aws</username>
            <password>${CODEARTIFACT_AUTH_TOKEN}</password>
          </server>
        </servers>
        <mirrors>
          <mirror>
            <id>codeartifact</id>
            <mirrorOf>*</mirrorOf>
            <url>${CA_ENDPOINT}/maven/${CA_MAVEN_REPO}/</url>
          </mirror>
        </mirrors>
      </settings>
      EOF

PHP + Composer avec un registre privé

Installez PHP et configurez Composer pour récupérer des packages à partir d’un registre privé Packagist ou Satis.
  • COMPOSER_REGISTRY_URL — URL de votre registre Composer privé (par ex. https://repo.packagist.com/<org>)
  • REGISTRY_USER — Nom d’utilisateur du registre
  • REGISTRY_PASS — Mot de passe du registre ou jeton d’API
initialize:
  - name: Install PHP and Composer
    run: |
      sudo apt-get update -qq
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
        php-cli php-mbstring php-xml php-curl unzip

      # Installer Composer
      curl -sS https://getcomposer.org/installer | php
      sudo mv composer.phar /usr/local/bin/composer

maintenance:
  - name: Configure Composer for private registry
    run: |
      composer config --global repositories.private \
        composer "$COMPOSER_REGISTRY_URL"

      # S'authentifier auprès du registre
      composer config --global http-basic.$(echo "$COMPOSER_REGISTRY_URL" \
        | sed 's|https\?://||;s|/.*||') "$REGISTRY_USER" "$REGISTRY_PASS"

      # Désactiver optionnellement le packagist.org par défaut
      # composer config --global repositories.packagist false
Schémas d’URL courants pour le registre Composer :
  • Artifactory: https://artifactory.example.com/artifactory/api/composer/packagist-virtual
  • Nexus: https://nexus.example.com/repository/packagist-proxy
  • Private Packagist: https://repo.packagist.com/<org>
  • Satis: https://satis.corp.internal

Exemples spécifiques au dépôt

Ces exemples configurent, pour chaque dépôt, les étapes de build, la gestion des dépendances et les entrées de Knowledge. Définissez-les dans Settings > Environment > [your repo].

Projet Node.js standard

Un projet Node.js typique avec des commandes de lint, de test et de build.
initialize: |
  npm install -g pnpm

maintenance: |
  pnpm install

knowledge:
  - name: lint
    contents: |
      Run `pnpm lint` to check for errors.
      Run `pnpm lint --fix` to auto-fix.
  - name: test
    contents: |
      Run `pnpm test` for the full test suite.
      Run `pnpm test -- --watch` during development.
  - name: build
    contents: |
      Run `pnpm build` to create a production build.
      Output goes to the `dist/` directory.

Projet Python standard

Un projet Python qui utilise uv pour gérer les dépendances.
initialize:
  - name: Install uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh

maintenance:
  - name: Sync dependencies
    run: uv sync

knowledge:
  - name: lint
    contents: |
      Run `uv run ruff check .` to lint.
      Run `uv run ruff format .` to format.
  - name: test
    contents: |
      Run `uv run pytest` for the full test suite.
      Run `uv run pytest -x` to stop on first failure.

Projet Java standard

Un projet Java utilisant Maven pour gérer les dépendances.
maintenance:
  - name: Resolve dependencies
    run: mvn dependency:resolve -U -q

knowledge:
  - name: build
    contents: |
      Run `mvn clean package` to build.
      Run `mvn clean package -DskipTests` to build without tests.
  - name: test
    contents: |
      Run `mvn test` for unit tests.
      Run `mvn verify` for integration tests.
  - name: lint
    contents: |
      Run `mvn checkstyle:check` for style checks.
      Run `mvn spotbugs:check` for bug detection.

Projet Go standard

Un projet Go avec les outils standard.
maintenance:
  - name: Download dependencies
    run: go mod download

knowledge:
  - name: build
    contents: |
      Run `go build ./...` to build all packages.
      Run `go build -o bin/app ./cmd/app` to build the main binary.
  - name: test
    contents: |
      Run `go test ./...` for all tests.
      Run `go test -race ./...` to include race detection.
      Run `go test -v ./pkg/... -run TestSpecific` for a specific test.
  - name: lint
    contents: |
      Run `golangci-lint run` for linting (if installed).
      Run `go vet ./...` for basic static analysis.

Projet Rust standard

Un projet Rust qui utilise Cargo.
maintenance:
  - name: Fetch dependencies
    run: cargo fetch

knowledge:
  - name: build
    contents: |
      Run `cargo build` for a debug build.
      Run `cargo build --release` for a release build.
  - name: test
    contents: |
      Run `cargo test` for all tests.
      Run `cargo test -- --test-threads=1` for sequential execution.
  - name: lint
    contents: |
      Run `cargo clippy -- -D warnings` for lint checks.
      Run `cargo fmt --check` to verify formatting.

Monorepo avec plusieurs services

Un monorepo avec des services front-end et back-end distincts qui utilisent des gestionnaires de paquets différents.
initialize:
  - name: Install pnpm
    run: npm install -g pnpm
  - name: Install uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh

maintenance:
  - name: Install frontend dependencies
    run: (cd packages/frontend && pnpm install)
  - name: Install backend dependencies
    run: (cd packages/backend && uv sync)
  - name: Build shared library
    run: (cd packages/shared && pnpm install && pnpm build)

knowledge:
  - name: structure
    contents: |
      This is a monorepo with three packages:
      - `packages/frontend` — React app (TypeScript, pnpm)
      - `packages/backend` — Python API (FastAPI, uv)
      - `packages/shared` — Shared TypeScript utilities (must be built before frontend)
  - name: frontend
    contents: |
      Run `cd packages/frontend && pnpm dev` to start the dev server.
      Run `cd packages/frontend && pnpm lint` to lint.
      Run `cd packages/frontend && pnpm test` to test.
  - name: backend
    contents: |
      Run `cd packages/backend && uv run uvicorn app.main:app --reload` to start the API.
      Run `cd packages/backend && uv run ruff check .` to lint.
      Run `cd packages/backend && uv run pytest` to test.
Utilisez des sous-shells (cd dir && command) plutôt que cd dir && command afin que le répertoire de travail soit réinitialisé entre les étapes.

Monorepo avec plusieurs versions de JDK

Un monorepo Java dans lequel différents services nécessitent des versions de JDK différentes. Installez les deux JDK lors de la configuration, puis utilisez des entrées Knowledge pour indiquer à Devin quelle valeur de JAVA_HOME utiliser pour chaque service.
initialize:
  - name: Install JDK 17 (primary)
    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: Install JDK 11 (legacy service)
    run: |
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-11-jdk-headless

maintenance:
  - name: Warm dependency caches
    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: |
      Build the API service (JDK 17):
        JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
        cd services/api && ./gradlew clean build
  - name: build_legacy
    contents: |
      Build the legacy service (JDK 11):
        JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
        cd services/legacy && ./gradlew clean build
  - name: test_all
    contents: |
      Run tests for all 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)

Hooks de pré-commit

Si votre projet utilise des hooks pre-commit, installez-les dans maintenance afin qu’ils soient prêts pour chaque session.
initialize:
  - name: Install pre-commit
    run: pip install pre-commit

maintenance:
  - name: Install pre-commit hooks
    run: pre-commit install --install-hooks
Si le projet inclut déjà pre-commit parmi ses dépendances de développement (par exemple dans pyproject.toml), ignorez l’étape initialize et utilisez plutôt uv run pre-commit install --install-hooks ou pipx run pre-commit install --install-hooks dans maintenance.

Entrées Knowledge détaillées

Documentez l’architecture, les conventions et les processus de votre projet dans des entrées knowledge.
knowledge:
  - name: architecture
    contents: |
      This is a microservices application:
      - `api-gateway/` — Express.js reverse proxy (port 3000)
      - `auth-service/` — JWT authentication service (port 3001)
      - `user-service/` — User CRUD service (port 3002)
      - `shared/` — Shared protobuf definitions and utilities

      Services communicate via gRPC. The API gateway is the only public-facing service.

  - name: conventions
    contents: |
      - All API responses use the `{ data, error, meta }` envelope format
      - Database migrations are in `migrations/` and run with `npm run migrate`
      - Environment-specific config is in `config/{env}.json`
      - Feature flags are managed via LaunchDarkly (SDK key in $LD_SDK_KEY)

  - name: testing
    contents: |
      Unit tests: `npm test`
      Integration tests: `npm run test:integration` (requires Docker for Postgres)
      E2E tests: `npm run test:e2e` (requires all services running)

      Coverage report: `npm run test:coverage` (must be > 80% for CI to pass)

  - name: deployment
    contents: |
      CI/CD runs on GitHub Actions. Merges to `main` auto-deploy to staging.
      Production deploys require a manual approval step in the Actions UI.
      Docker images are pushed to ECR: 123456789.dkr.ecr.us-east-1.amazonaws.com/

Exemples combinés

Ces exemples montrent comment les configurations à l’échelle de l’entreprise et au niveau de l’organisation se combinent. En pratique, vous les répartiriez entre différents périmètres — ils sont regroupés ici à titre de référence.

Stack d’entreprise complète

Un environnement d’entreprise complet : certificat d’autorité de certification d’entreprise, proxy, Java (Maven), Python (pip/uv), Node.js (npm) et Docker — tous configurés pour pointer vers une seule instance Artifactory.
Réseau et confiance (à l’é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 à exclure du proxy
Identifiants du registre (à l’échelle de l’organisation) :
  • ARTIFACTORY_USER — Nom d’utilisateur Artifactory
  • ARTIFACTORY_TOKEN — Jeton d’API ou mot de passe Artifactory
  • ARTIFACTORY_MAVEN_URL — URL du dépôt Maven (par ex., https://artifactory.example.com/artifactory/maven-virtual)
  • ARTIFACTORY_PYPI_URL — URL du dépôt PyPI (par ex., https://user:token@artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple)
  • ARTIFACTORY_NPM_URL — URL du dépôt npm (par ex., https://artifactory.example.com/artifactory/api/npm/npm-virtual)
  • ARTIFACTORY_DOCKER_URL — URL du registre Docker (par ex., artifactory.example.com)
Cela serait généralement réparti sur trois périmètres :
  • À l’échelle du compte (initialize) : certificat et proxy
  • À l’échelle de l’organisation (initialize) : installation des environnement d’exécution de langage
  • À l’échelle de l’organisation (maintenance) : identifiants du registre (actualisés à chaque session)
Présenté ici de façon combinée à titre de référence :
initialize:
  # ── À l'échelle du compte : réseau et confiance ──────────────────────────────────────

  - name: Install corporate 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

  - name: Configure system-wide 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

  # ── À l'échelle de l'organisation : environnements d'exécution des langages ──────────────────────────────────────────

  - name: Install JDK 17 + Maven
    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

      MAVEN_VERSION=3.9.9
      curl -fsSL "https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz" \
        | sudo tar -xz -C /opt
      sudo ln -sf /opt/apache-maven-${MAVEN_VERSION}/bin/mvn /usr/local/bin/mvn

  - name: Install uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh

maintenance:
  # ── À l'échelle du compte : proxy git (actualisé à chaque session) ───────────────────

  - name: Configure git proxy
    run: |
      git config --global http.proxy "$CORP_HTTP_PROXY"
      git config --global https.proxy "$CORP_HTTPS_PROXY"

  # ── À l'échelle de l'organisation : identifiants de registre (actualisés à chaque session) ──────────────

  - name: Configure Maven → Artifactory
    run: |
      mkdir -p ~/.m2
      cat > ~/.m2/settings.xml << EOF
      <settings>
        <mirrors>
          <mirror>
            <id>artifactory</id>
            <mirrorOf>*</mirrorOf>
            <url>$ARTIFACTORY_MAVEN_URL</url>
          </mirror>
        </mirrors>
        <servers>
          <server>
            <id>artifactory</id>
            <username>$ARTIFACTORY_USER</username>
            <password>$ARTIFACTORY_TOKEN</password>
          </server>
        </servers>
      </settings>
      EOF

  - name: Configure pip/uv → Artifactory PyPI
    run: |
      mkdir -p ~/.config/pip
      cat > ~/.config/pip/pip.conf << EOF
      [global]
      index-url = $ARTIFACTORY_PYPI_URL
      trusted-host = $(echo "$ARTIFACTORY_PYPI_URL" | sed 's|https\?://||;s|/.*||')
      EOF

      echo "export UV_INDEX_URL=$ARTIFACTORY_PYPI_URL" \
        | sudo tee /etc/profile.d/uv-registry.sh > /dev/null

  - name: Configure npm → Artifactory
    run: |
      npm config set registry "$ARTIFACTORY_NPM_URL"
      REGISTRY_HOST=$(echo "$ARTIFACTORY_NPM_URL" | sed 's|https\?://||;s|/.*||')
      npm config set "//${REGISTRY_HOST}/:_authToken" "$ARTIFACTORY_TOKEN"

  - name: Configure Docker → Artifactory
    run: |
      echo "$ARTIFACTORY_TOKEN" | docker login "$ARTIFACTORY_DOCKER_URL" \
        --username "$ARTIFACTORY_USER" \
        --password-stdin
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 des registres différents

Lorsque différents langages utilisent différents registres privés (par ex. Maven via Nexus, npm via GitHub Packages, Python via Artifactory).
  • 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
maintenance:
  # Maven → Nexus
  - name: Configure Maven → Nexus
    run: |
      mkdir -p ~/.m2
      cat > ~/.m2/settings.xml << EOF
      <settings>
        <mirrors>
          <mirror>
            <id>nexus</id>
            <mirrorOf>*</mirrorOf>
            <url>$NEXUS_MAVEN_URL</url>
          </mirror>
        </mirrors>
        <servers>
          <server>
            <id>nexus</id>
            <username>$NEXUS_USER</username>
            <password>$NEXUS_PASS</password>
          </server>
        </servers>
      </settings>
      EOF

  # npm → GitHub Packages (scoped)
  - name: Configure npm → GitHub Packages
    run: |
      npm config set @myorg:registry https://npm.pkg.github.com
      npm config set //npm.pkg.github.com/:_authToken $GITHUB_PACKAGES_TOKEN

  # Python → Artifactory
  - name: Configure pip → Artifactory
    run: |
      mkdir -p ~/.config/pip
      cat > ~/.config/pip/pip.conf << EOF
      [global]
      index-url = https://$ARTIFACTORY_USER:$ARTIFACTORY_TOKEN@artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple
      EOF

  # Go → modules privés via git
  - name: Configure Go private modules
    run: |
      git config --global url."https://$GIT_TOKEN@github.com/myorg/".insteadOf "https://github.com/myorg/"

Environnement en air gap avec miroirs privés

Dans un environnement entièrement 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.
Certificats :
  • CORP_ROOT_CA_B64 — certificat d’autorité de certification d’entreprise encodé en Base64
Accès au miroir :
  • APT_MIRROR_URL — URL du miroir APT Ubuntu interne
  • MIRROR_USER — nom d’utilisateur pour l’authentification au miroir
  • MIRROR_PASS — mot de passe pour l’authentification au miroir
  • JDK_TARBALL_URL — URL de téléchargement de l’archive JDK depuis le miroir interne
  • NODE_TARBALL_URL — URL de téléchargement de l’archive Node.js depuis le miroir interne
Registres de packages :
  • INTERNAL_MAVEN_URL — URL du registre Maven interne
  • INTERNAL_NPM_URL — URL du registre npm interne
  • INTERNAL_PYPI_URL — URL du registre PyPI interne
initialize:
  - name: Install corporate 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

  - name: Replace apt sources with internal mirror
    run: |
      sudo sed -i "s|http://archive.ubuntu.com/ubuntu|$APT_MIRROR_URL|g" /etc/apt/sources.list
      sudo sed -i "s|http://security.ubuntu.com/ubuntu|$APT_MIRROR_URL|g" /etc/apt/sources.list
      sudo apt-get update -qq

  - name: Install JDK from internal mirror
    run: |
      # Télécharger l'archive JDK depuis le dépôt d'artefacts interne
      curl -fsSL -u "$MIRROR_USER:$MIRROR_PASS" "$JDK_TARBALL_URL" \
        | sudo tar -xz -C /usr/local
      sudo ln -sf /usr/local/jdk-17.*/bin/java /usr/local/bin/java
      sudo ln -sf /usr/local/jdk-17.*/bin/javac /usr/local/bin/javac
      echo "export JAVA_HOME=$(ls -d /usr/local/jdk-17.*)" \
        | sudo tee /etc/profile.d/java.sh > /dev/null

  - name: Install Node.js from internal mirror
    run: |
      curl -fsSL -u "$MIRROR_USER:$MIRROR_PASS" "$NODE_TARBALL_URL" \
        | sudo tar -xz -C /usr/local --strip-components=1

maintenance:
  - name: Configure all package managers for internal registry
    run: |
      # Maven
      mkdir -p ~/.m2
      cat > ~/.m2/settings.xml << EOF
      <settings>
        <mirrors>
          <mirror>
            <id>internal</id>
            <mirrorOf>*</mirrorOf>
            <url>$INTERNAL_MAVEN_URL</url>
          </mirror>
        </mirrors>
        <servers>
          <server>
            <id>internal</id>
            <username>$MIRROR_USER</username>
            <password>$MIRROR_PASS</password>
          </server>
        </servers>
      </settings>
      EOF

      # npm
      npm config set registry "$INTERNAL_NPM_URL"

      # pip
      mkdir -p ~/.config/pip
      cat > ~/.config/pip/pip.conf << EOF
      [global]
      index-url = $INTERNAL_PYPI_URL
      EOF
Dans les environnements cloisonnés (air-gapped), tous les outils dont Devin a besoin (environnements d’exécution, outils CLI, etc.) doivent être disponibles sur vos miroirs internes. Les registres publics et les sites de téléchargement sont inaccessibles.

VPN + certificats + proxy + langages

Une configuration d’entreprise complète combinant la connectivité VPN avec des certificats, un proxy et la prise en charge de plusieurs langages. Voici l’ordre des opérations recommandé.
VPN:
  • VPN_CONFIG_B64 — Fichier de configuration OpenVPN encodé en Base64
Réseau et 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 à exclure du 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ésoudre les 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 — faire confiance aux 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 | sh

maintenance:
  - 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 être configuré en premier (pour que les hôtes internes soient accessibles), puis le DNS (pour que les noms se résolvent), 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).

Conseils pour rédiger de bonnes configurations

  • Testez d’abord les commandes dans une session — exécutez-les manuellement dans une session Devin avant de les ajouter à votre configuration. C’est plus rapide que d’attendre un cycle de build complet.
  • Utilisez initialize pour les outils à installer une seule fois, maintenance pour les dépendances — tout ce qui prend plusieurs minutes à installer (compilateurs, binaires volumineux, 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 d’environnement d’une étape et d’une session à l’autre.
  • Nommez vos étapes — la forme développée avec des champs name permet de repérer bien plus facilement les échecs dans les journaux de build.
  • Utilisez des sous-shells pour les monorepos(cd packages/foo && npm install) s’exécute dans un sous-shell afin que les étapes suivantes ne soient pas affectées par le changement de répertoire.
Pour en savoir plus sur la syntaxe et les détails d’exécution, consultez la Référence YAML. Pour résoudre les échecs de build, consultez Dépannage et FAQ.