> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Devin ブループリントテンプレートライブラリ

> 一般的な言語、非公開レジストリ、Enterprise インフラストラクチャ 向けのブループリントテンプレートで Devin の environment を構成します。

一般的な言語やユースケース向けに、コピー&ペーストして使えるブループリントを用意しています。これらを組み合わせて、完全な configuration を構築してください。使用例は Linux 上の Bash を前提としています。サンプルのホスト、scope、コマンドはご自身の環境に合わせて置き換えてください。

各フィールドの詳細については、[Blueprint reference](/ja/onboard-devin/environment/blueprint-reference) を参照してください。

<Info>
  **シークレット:** 各ブループリントエディタ内の **Secrets** タブで、名前付きシークレットを configure してください。build step には該当するブループリントのシークレットが渡されます。セッション中は、各コマンドが必要なシークレットを確実に受け取れるようにしてください。repo scope のシークレットには、`env={"REGISTRY_TOKEN": "secret:repo:owner/repo:REGISTRY_TOKEN"}` のように `exec` の environment バインドを明示的に指定する必要があります。詳しくは [Secrets](/ja/product-guides/secrets) を参照してください。認証情報をブループリントにハードコードしないでください。
</Info>

<Warning>
  **build step はセッション起動時のフックではありません。** `initialize` と `maintenance` はスナップショットの build 中に実行されます。`maintenance` はセッション開始時に自動実行されるわけではありません。`knowledge` は Devin に instructions を提供するものであり、実行可能なフックではありません。

  `$ENVRC` を含め、永続的なファイルに認証情報を残さないでください。スナップショットのクリーンアップで削除されるのは Devin が注入したシークレットファイルであり、ユーザーのコマンドが書き込んだ任意のファイルは削除されません。利用するツールがサポートする変数参照をそのまま使うか、コマンドの environment で認証情報を渡してください。ツールが認証情報ファイルを必要とする場合は、1 回の操作のためだけに作成し、終了前にクリーンアップしてください。セッション内で必要になった場合は、その setup を都度明示的に繰り返してください。
</Warning>

***

<div id="quick-start">
  ## クイックスタート
</div>

よくあるセットアップ向けの最小構成のブループリントです。1 つをコピーしてブループリントエディタに貼り付ければ完了です。

<AccordionGroup>
  <Accordion title="Node.js プロジェクト">
    ```yaml theme={null}
    initialize: |
      npm install -g pnpm

    maintenance: |
      pnpm install

    knowledge:
      - name: lint
        contents: |
          エラーを確認するには `pnpm lint` を実行します。
      - name: test
        contents: |
          フルスイートを実行するには `pnpm test` を実行します。
    ```
  </Accordion>

  <Accordion title="Python プロジェクト">
    ```yaml theme={null}
    initialize: |
      curl -LsSf https://astral.sh/uv/install.sh | sh

    maintenance: |
      uv sync

    knowledge:
      - name: lint
        contents: |
          lint を実行するには `uv run ruff check .` を実行します。
      - name: test
        contents: |
          フルスイートを実行するには `uv run pytest` を実行します。
    ```
  </Accordion>

  <Accordion title="フルスタック（Node + Python）">
    ```yaml theme={null}
    initialize:
      - name: pnpmをインストールする
        run: npm install -g pnpm
      - name: uvをインストールする
        run: curl -LsSf https://astral.sh/uv/install.sh | sh

    maintenance:
      - name: フロントエンドの依存関係
        run: (cd frontend && pnpm install)
      - name: バックエンドの依存関係
        run: (cd backend && uv sync)

    knowledge:
      - name: structure
        contents: |
          - `frontend/` — React アプリ（pnpm）
          - `backend/` — Python API（uv）
      - name: test
        contents: |
          フロントエンド: cd frontend && pnpm test
          バックエンド: cd backend && uv run pytest
    ```
  </Accordion>
</AccordionGroup>

***

<div id="repository-blueprints">
  ## リポジトリのブループリント
</div>

リポジトリごとのビルド手順、依存関係管理、Knowledge エントリ。これらは **Settings > Environment > Blueprints > \[ご利用のリポジトリ]** で設定します。

<div id="python">
  ### Python
</div>

<Tabs>
  <Tab title="uv（推奨）">
    依存関係の管理に [uv](https://docs.astral.sh/uv/) を利用する Python プロジェクト向けの推奨セットアップです。

    ```yaml theme={null}
    initialize: |
      curl -LsSf https://astral.sh/uv/install.sh | sh

    maintenance: |
      uv sync

    knowledge:
      - name: lint
        contents: |
          uv run ruff check .

          自動修正:
          uv run ruff check --fix .

      - name: test
        contents: |
          uv run pytest

      - name: build
        contents: |
          uv run python -m build
    ```
  </Tab>

  <Tab title="pip + venv">
    pip と venv を使った従来の Python セットアップです。プロジェクトで `requirements.txt` を利用している場合に使用してください。

    ```yaml theme={null}
    initialize: |
      python3 -m venv .venv

    maintenance: |
      source .venv/bin/activate
      pip install -r requirements.txt

    knowledge:
      - name: lint
        contents: |
          source .venv/bin/activate
          flake8 .

      - name: test
        contents: |
          source .venv/bin/activate
          pytest

      - name: build
        contents: |
          source .venv/bin/activate
          python -m build
    ```
  </Tab>
</Tabs>

<div id="nodejs">
  ### Node.js
</div>

<Tabs>
  <Tab title="npm">
    npm を使う標準的な Node.js のセットアップです。

    ```yaml theme={null}
    initialize: |
      nvm install 20
      nvm use 20

    maintenance: |
      npm install

    knowledge:
      - name: lint
        contents: |
          npx eslint .

      - name: test
        contents: |
          npm test

      - name: build
        contents: |
          npm run build
    ```

    <Info>
      `maintenance` では `npm ci` ではなく `npm install` を利用してください。`npm install` は差分更新を行いますが、`npm ci` はコマンドが実行されるたびに `node_modules` を削除し、すべてを最初から再インストールします。
    </Info>
  </Tab>

  <Tab title="pnpm">
    pnpm を利用するプロジェクト向けです。

    ```yaml theme={null}
    initialize: |
      npm install -g pnpm

    maintenance: |
      pnpm install --frozen-lockfile

    knowledge:
      - name: lint
        contents: |
          pnpm lint

      - name: test
        contents: |
          pnpm test

      - name: build
        contents: |
          pnpm build
    ```
  </Tab>
</Tabs>

<div id="go">
  ### Go
</div>

モジュールを使用した標準的なGoのセットアップ。

```yaml theme={null}
initialize: |
  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

  go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

maintenance: |
  go mod download

knowledge:
  - name: lint
    contents: |
      golangci-lint run

  - name: test
    contents: |
      go test ./...

  - name: build
    contents: |
      go build ./...
```

<div id="java">
  ### Java
</div>

<Tabs>
  <Tab title="Gradle">
    Gradle を使用する Java のセットアップ。

    <Info>JDK 17 は Devin のベースイメージに**プリインストール**されています。デフォルトの OpenJDK 17 で十分な場合は、JDK のインストール手順をスキップしてください。</Info>

    ```yaml theme={null}
    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: |
      ./gradlew dependencies

    knowledge:
      - name: lint
        contents: |
          ./gradlew check

      - name: test
        contents: |
          ./gradlew test

      - name: build
        contents: |
          ./gradlew build
    ```
  </Tab>

  <Tab title="Maven">
    Maven を使用する Java のセットアップ。

    <Info>JDK 17 は Devin のベースイメージに**プリインストール**されています。デフォルトの OpenJDK 17 で十分な場合は、JDK のインストール手順をスキップしてください。</Info>

    ```yaml theme={null}
    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: |
      mvn dependency:resolve

    knowledge:
      - name: test
        contents: |
          mvn test

      - name: build
        contents: |
          mvn package
    ```
  </Tab>
</Tabs>

<div id="ruby-on-rails">
  ### Ruby on Rails
</div>

PostgreSQL を使用する Rails のセットアップ。

```yaml theme={null}
initialize:
  - name: Install Ruby 3.3
    run: |
      sudo apt-get update -qq
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ruby-full libpq-dev postgresql-client

maintenance: |
  bundle install
  rails db:migrate

knowledge:
  - name: lint
    contents: |
      bundle exec rubocop

  - name: test
    contents: |
      bundle exec rspec

  - name: build
    contents: |
      rails assets:precompile
```

<div id="rust">
  ### Rust
</div>

cargo を使った標準的な Rust のセットアップ。

<Info>**Rust** (rustup 経由) と **Cargo** は、Devin のベースイメージに**あらかじめインストール**されています。デフォルトの安定版ツールチェーンで十分な場合は、インストール手順は省略できます。必要なのは依存関係の取得だけです。</Info>

```yaml theme={null}
initialize: |
  curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
  source ~/.cargo/env

maintenance: |
  cargo fetch

knowledge:
  - name: lint
    contents: |
      cargo clippy -- -D warnings

  - name: test
    contents: |
      cargo test

  - name: build
    contents: |
      cargo build --release
```

<div id="monorepos">
  ### モノレポ
</div>

<Tabs>
  <Tab title="マルチ言語">
    Node.js のフロントエンドと Python のバックエンドを持つモノレポです。各サブプロジェクトには、それぞれ専用のKnowledge エントリを設定します。

    ```yaml theme={null}
    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: |
          これは 3 つのパッケージで構成されたモノレポです:
          - `packages/frontend` — React アプリ（TypeScript、pnpm）
          - `packages/backend` — Python API（FastAPI、uv）
          - `packages/shared` — 共有 TypeScript ユーティリティ（フロントエンドより先にビルドが必要）
      - name: frontend
        contents: |
          開発サーバーを起動するには、`cd packages/frontend && pnpm dev` を実行します。
          lint を実行するには、`cd packages/frontend && pnpm lint` を実行します。
          テストを実行するには、`cd packages/frontend && pnpm test` を実行します。
      - name: backend
        contents: |
          API を起動するには、`cd packages/backend && uv run uvicorn app.main:app --reload` を実行します。
          lint を実行するには、`cd packages/backend && uv run ruff check .` を実行します。
          テストを実行するには、`cd packages/backend && uv run pytest` を実行します。
    ```

    <Tip>
      ステップ間で作業ディレクトリがリセットされるように、`cd dir && command` ではなくサブシェル `(cd dir && command)` を利用してください。
    </Tip>
  </Tab>

  <Tab title="複数の JDK バージョン">
    サービスごとに異なる JDK バージョンが必要な Java モノレポです。セットアップ時に両方の JDK をインストールし、その後 `knowledge` エントリを利用して、各サービスでどの `JAVA_HOME` を使うかを Devin に伝えます。

    ```yaml theme={null}
    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: |
          API サービスをビルドします（JDK 17）:
            JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
            cd services/api && ./gradlew clean build
      - name: build_legacy
        contents: |
          レガシーサービスをビルドします（JDK 11）:
            JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
            cd services/legacy && ./gradlew clean build
      - name: test_all
        contents: |
          すべてのサービスのテストを実行します:
            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)
    ```
  </Tab>
</Tabs>

***

<div id="private-package-registries">
  ## 非公開パッケージレジストリ
</div>

非公開レジストリから依存関係を解決するようにパッケージマネージャーを設定します。設定は **Settings > Environment > Blueprints > Org-wide setup** で行います (1つのリポジトリでのみ必要な場合はリポジトリ単位で設定) 。

<Warning>
  **展開済みの認証情報ではなく、参照を保存してください。** `<<'EOF'` のように引用符付きのヒアドキュメント区切り文字を使うと、ファイル内に変数参照がそのまま保持されます。npm、Yarn Berry、Maven、Gradle は、実行時に以下の参照を解決できます。pip は `pip.conf` 内のシェル変数を展開しないため、代わりに環境変数を利用してください。シェルのセットアップファイルは、ツールと同じコマンド内で明示的に読み込む必要があります。新しいシェルが自動的に読み込んだり、認証情報を更新したりすることを前提にしないでください。

  Cargo のインデックス、Docker ミラー、APT ミラーなど、永続的な設定に直接書き込む URL に認証情報を含めてはいけません。認証は、各テンプレートで示されている個別のシークレットに分離して保持してください。

  認証情報をディスクに書き込む古いテンプレートを利用していた場合は、該当ファイルを削除し、それらを含むスナップショットではなくクリーンなベースから再ビルドしてください。漏洩した可能性のある認証情報はローテーションしてください。
</Warning>

<Info>
  非公開レジストリが企業の CA を利用している場合は、まず [CA 証明書](#corporate-ca-certificate) が Enterprise レベルでインストールされていることを確認してください。以下の設定は、HTTPS の信頼関係がすでに確立されていることを前提としています。
</Info>

<div id="nodejs-registries">
  ### Node.js レジストリ
</div>

<Tabs>
  <Tab title="npm (scoped)">
    npm を設定して、スコープ付きパッケージ (例: `@myorg/*`) は非公開レジストリから取得し、公開パッケージは引き続きデフォルトの npm レジストリから取得するようにします。

    <Accordion title="必要なシークレット">
      * `GITHUB_PACKAGES_TOKEN` — `read:packages` スコープを持つパーソナルアクセストークン、または GitHub App トークン
    </Accordion>

    ```yaml theme={null}
    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}'
    ```

    <Tip>
      `@myorg` は実際の npm スコープに置き換えてください。一般的な非公開レジストリ URL:

      * **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>`
    </Tip>
  </Tab>

  <Tab title="npm (full mirror)">
    **すべての** npm パッケージを非公開レジストリ経由にします (スコープ付きパッケージだけではありません)。

    <Accordion title="必要なシークレット">
      * `NPM_REGISTRY_URL` — npm レジストリの完全な URL (例: `https://artifactory.example.com/artifactory/api/npm/npm-virtual`)
      * `NPM_REGISTRY_HOST` — プロトコルを含まないホスト名のみ (例: `artifactory.example.com`)
      * `REGISTRY_TOKEN` — レジストリ用の npm 認証トークン
    </Accordion>

    ```yaml theme={null}
    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
    ```
  </Tab>

  <Tab title="pnpm">
    pnpm を設定して、パッケージを非公開レジストリから取得するようにします。

    <Accordion title="必要なシークレット">
      * `NPM_REGISTRY_URL` — npm レジストリの完全な URL
      * `NPM_REGISTRY_HOST` — プロトコルを含まないホスト名のみ
      * `REGISTRY_TOKEN` — レジストリ用の npm 認証トークン
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Install pnpm
        run: npm install -g pnpm

    maintenance:
      - name: Configure pnpm for private registry
        run: |
          npm config set registry '${NPM_REGISTRY_URL}'
          npm config set "//${NPM_REGISTRY_HOST}/:_authToken" '${REGISTRY_TOKEN}'
    ```
  </Tab>

  <Tab title="Yarn">
    Yarn (Classic v1 または Berry v2+) を設定して、パッケージを非公開レジストリから取得するようにします。

    <Accordion title="必要なシークレット">
      * `NPM_REGISTRY_URL` — npm/Yarn レジストリの完全な URL
      * `REGISTRY_TOKEN` — レジストリ用の認証トークン
    </Accordion>

    **Yarn Classic (v1):**

    ```yaml theme={null}
    initialize:
      - name: Install Yarn Classic
        run: npm install -g yarn

    maintenance:
      - name: Configure Yarn for private registry
        run: |
          npm config set registry '${NPM_REGISTRY_URL}'
          npm config set //registry.example.com/:_authToken '${REGISTRY_TOKEN}'
    ```

    `registry.example.com` は実際のレジストリホストに置き換えてください。Yarn Classic は npm の `.npmrc` を読み取ります。

    **Yarn Berry (v2+):**

    ```yaml theme={null}
    maintenance:
      - name: Configure Yarn Berry for private registry
        run: |
          yarn config set npmRegistryServer '${NPM_REGISTRY_URL}'
          yarn config set npmAuthToken '${REGISTRY_TOKEN}'
          # スコープ付きパッケージの場合:
          # yarn config set npmScopes.myorg.npmRegistryServer "https://npm.pkg.github.com"
          # yarn config set npmScopes.myorg.npmAuthToken '${GITHUB_PACKAGES_TOKEN}'
    ```
  </Tab>
</Tabs>

<div id="python-registries">
  ### Python レジストリ
</div>

<Tabs>
  <Tab title="pip / uv">
    pip と uv が非公開の PyPI レジストリ (例: Nexus、Artifactory) からパッケージを取得できるように設定します。

    <Accordion title="必要なシークレット">
      * `PYPI_REGISTRY_URL` — 必要に応じて認証情報を含む、PyPI インデックスの完全な URL (例: `https://user:token@nexus.example.com/repository/pypi-proxy/simple`)
    </Accordion>

    ```yaml theme={null}
    maintenance:
      - name: Configure pip/uv for private registry
        run: |
          mkdir -p ~/.config
          cat > ~/.config/private-pypi.sh <<'EOF'
          export PIP_INDEX_URL="$PYPI_REGISTRY_URL"
          export UV_INDEX_URL="$PYPI_REGISTRY_URL"
          EOF

    knowledge:
      - name: private_python_packages
        contents: |
          With PYPI_REGISTRY_URL available in the command's environment, run:
            source ~/.config/private-pypi.sh && uv sync
          Or:
            source ~/.config/private-pypi.sh && pip install -r requirements.txt
    ```

    ビルド中に依存関係を事前に取得しておくには、設定ステップの後に同じ `source ... &&` コマンドを `maintenance` に追加します。URL の認証情報に含まれる特殊文字はパーセントエンコードしてください。

    <Tip>
      一般的な PyPI レジストリ URL パターン:

      * **Artifactory:** `https://artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple`
      * **Nexus:** `https://nexus.example.com/repository/pypi-proxy/simple`
      * **AWS CodeArtifact:** `https://aws:TOKEN@domain-owner.d.codeartifact.region.amazonaws.com/pypi/repo/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`
    </Tip>
  </Tab>

  <Tab title="Poetry">
    Poetry が非公開の PyPI レジストリからパッケージを取得できるように設定します。

    <Accordion title="必要なシークレット">
      * `POETRY_REGISTRY_URL` — PyPI 互換レジストリの完全な URL
      * `REGISTRY_USER` — レジストリのユーザー名
      * `REGISTRY_PASS` — レジストリのパスワードまたは API トークン
    </Accordion>

    ```yaml theme={null}
    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 "$POETRY_REGISTRY_URL"
          mkdir -p ~/.config
          cat > ~/.config/private-poetry.sh <<'EOF'
          export POETRY_HTTP_BASIC_PRIVATE_USERNAME="$REGISTRY_USER"
          export POETRY_HTTP_BASIC_PRIVATE_PASSWORD="$REGISTRY_PASS"
          EOF

    knowledge:
      - name: private_poetry_packages
        contents: |
          With REGISTRY_USER and REGISTRY_PASS available, run:
            source ~/.config/private-poetry.sh && poetry install
    ```

    依存関係をインストールするには、プロジェクトの `pyproject.toml` にも `private` パッケージソースを宣言してください。`poetry config repositories.private` は公開先リポジトリを設定するものであり、環境の認証情報は一致するソース名に対して適用されます。
  </Tab>
</Tabs>

<div id="jvm-registries">
  ### JVM 用レジストリ
</div>

<Tabs>
  <Tab title="Maven">
    JDK をインストールし、すべての依存関係の解決が非公開レジストリ (例: Artifactory、Nexus) を経由するように Maven を設定します。

    <Info>
      Devin のベースイメージには JDK 17 が**プリインストール**されています。デフォルトの OpenJDK 17 で十分な場合は、インストール手順をスキップしてください。必要なのは Maven のインストールとレジストリ設定のみです。
    </Info>

    <Accordion title="必要なシークレット">
      * `MAVEN_REGISTRY_URL` — Maven レジストリの URL (例: `https://artifactory.example.com/artifactory/maven-virtual`)
      * `REGISTRY_USER` — レジストリのユーザー名
      * `REGISTRY_PASS` — レジストリのパスワードまたは API トークン
    </Accordion>

    ```yaml theme={null}
    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>${env.MAVEN_REGISTRY_URL}</url>
              </mirror>
            </mirrors>
            <servers>
              <server>
                <id>private-registry</id>
                <username>${env.REGISTRY_USER}</username>
                <password>${env.REGISTRY_PASS}</password>
              </server>
            </servers>
          </settings>
          EOF
    ```

    <Tip>
      Mavenでよく使われるレジストリURLのパターン:

      * **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>`
    </Tip>
  </Tab>

  <Tab title="Gradle">
    JDK をインストールし、すべての依存関係を非公開レジストリ経由で解決するように Gradle を設定します。

    <Info>
      JDK 17 は Devin のベースイメージに **プリインストール** されています。デフォルト設定で十分な場合は、JDK のインストール手順をスキップしてください。
    </Info>

    <Accordion title="必要なシークレット">
      * `GRADLE_REGISTRY_URL` — 使用する Gradle/Maven レジストリの URL
      * `REGISTRY_USER` — レジストリのユーザー名
      * `REGISTRY_PASS` — レジストリのパスワードまたは API トークン
    </Accordion>

    ```yaml theme={null}
    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 System.getenv("GRADLE_REGISTRY_URL")
                      credentials {
                          username = System.getenv("REGISTRY_USER")
                          password = System.getenv("REGISTRY_PASS")
                      }
                      allowInsecureProtocol = false
                  }
              }
          }
          EOF
    ```
  </Tab>
</Tabs>

<div id="other-registries">
  ### その他のレジストリ
</div>

<AccordionGroup>
  <Accordion title="Go モジュールプロキシ">
    Go をインストールし、非公開のモジュールプロキシ (Athens、Artifactory、GOPROXY エンドポイントなど) 経由でモジュールを解決するように設定します。

    <Accordion title="必要なシークレット">
      * `GO_PROXY_URL` — Go モジュールプロキシの URL (例: `https://athens.corp.internal`)
    </Accordion>

    Git provider を接続し、[Git 統合](/ja/integrations/overview)を通じて非公開モジュールをホストするリポジトリへのアクセスを許可します。Devin に設定済みの認証情報を用いて、通常の HTTPS 形式の Git URL を利用してください。Git URL の書き換えに token を埋め込まないでください。

    ```yaml theme={null}
    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

    knowledge:
      - name: private_go_modules
        contents: |
          From the repository root, with GO_PROXY_URL available, run:
            source /etc/profile.d/go-private.sh && go mod download
    ```

    ビルド時にモジュールキャッシュをウォームアップするには、`go.mod` が参照できる**リポジトリ**ブループリントの `maintenance` にそのコマンドを追加してください。org-wide setup はリポジトリがクローンされる前に実行されるため、そこでは実行しないでください。

    <Tip>
      一般的な Go の proxy URL のパターン:

      * **Artifactory:** `https://artifactory.example.com/artifactory/go-virtual`
      * **Nexus:** `https://nexus.example.com/repository/go-proxy`
      * **Athens:** `https://athens.corp.internal`
    </Tip>
  </Accordion>

  <Accordion title=".NET / NuGet">
    非公開フィードからパッケージを解決するように NuGet を設定します。

    <Accordion title="必要なシークレット">
      * `NUGET_SOURCE_URL` — NuGet フィードの URL
      * `NuGetPackageSourceCredentials_private` — NuGet の環境変数形式でのフィード認証情報: `Username=any;Password=<PAT>` (フィードで required なユーザー名を利用してください)
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Install .NET SDK
        run: |
          curl -fsSL https://dot.net/v1/dotnet-install.sh | bash -s -- --channel 8.0
          echo 'export PATH="$HOME/.dotnet:$PATH"' \
            | sudo tee /etc/profile.d/dotnet.sh > /dev/null

    maintenance:
      - name: Configure NuGet for private feed
        run: |
          dotnet nuget add source "$NUGET_SOURCE_URL" \
            --name private 2>/dev/null || \
          dotnet nuget update source private \
            --source "$NUGET_SOURCE_URL"

    knowledge:
      - name: private_nuget_packages
        contents: |
          Run dotnet restore with NuGetPackageSourceCredentials_private in its
          environment. The suffix must match the source name "private".
    ```
  </Accordion>

  <Accordion title="Docker">
    非公開のコンテナレジストリからプルできるよう Docker を設定します。

    Docker のログインでは、認証情報が config ディレクトリに書き込まれることがあります。操作ごとに分離したディレクトリを利用し、プルが失敗した場合でもそのディレクトリを削除してください。セッション中に別のイメージが必要になった場合は、ログインとプルの手順を再度実行します。

    <Accordion title="必要なシークレット">
      * `DOCKER_MIRROR_URL` *(任意)* — Docker Hub ミラーの URL (例: `https://mirror.corp.internal`)
      * `DOCKER_REGISTRY_URL` — 非公開コンテナレジストリの URL (例: `registry.corp.internal:5000`)
      * `DOCKER_REGISTRY_USER` — レジストリのユーザー名
      * `DOCKER_REGISTRY_PASS` — レジストリのパスワードまたは API トークン
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Create Docker config directory
        run: sudo mkdir -p /etc/docker

    maintenance:
      - name: Configure Docker for private registry
        run: |
          # レジストリミラーを設定（任意 — Docker Hub からの pull を自社レジストリ経由にします）
          cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
          {
            "registry-mirrors": ["$DOCKER_MIRROR_URL"]
          }
          EOF
          sudo systemctl restart docker || true

    knowledge:
      - name: private_container_images
        contents: |
          With the registry secrets available, run this in one shell.
          Replace team/image:tag with the image to pull:
            (
              set -euo pipefail
              umask 077
              DOCKER_CONFIG=$(mktemp -d)
              export DOCKER_CONFIG
              trap 'rm -rf "$DOCKER_CONFIG"' EXIT
              printf '%s' "$DOCKER_REGISTRY_PASS" |
                docker login "$DOCKER_REGISTRY_URL" \
                  --username "$DOCKER_REGISTRY_USER" --password-stdin
              docker pull "$DOCKER_REGISTRY_URL/team/image:tag"
            )
    ```

    スナップショットにイメージをキャッシュするには、同じサブシェル全体をビルドステップに記述します。ログインとクリーンアップを複数のステップに分割せず、イメージ化の前にクリーンアップが成功したことを確認してください。レジストリのミラー URL に認証情報を含めてはいけません。

    <Tip>
      一般的なコンテナレジストリの URL:

      * **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`
    </Tip>
  </Accordion>

  <Accordion title="Rust / Cargo">
    非公開レジストリからクレートを取得できるように Cargo を設定します。

    <Info>
      **Rust** (rustup 経由) と **Cargo** は Devin のベースイメージに**プリインストール**されています。デフォルトの stable ツールチェーンで十分な場合は、インストール手順を省略してください。必要なのはレジストリの設定のみです。
    </Info>

    <Accordion title="必要なシークレット">
      * `CARGO_REGISTRY_INDEX` — 非公開レジストリのインデックスの URL (例: `sparse+https://cargo.corp.internal/api/v1/crates/`)
      * `CARGO_REGISTRIES_PRIVATE_TOKEN` — `private` という名前のレジストリ用の認証トークン
    </Accordion>

    ```yaml theme={null}
    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
          [registry]
          global-credential-providers = ["cargo:token"]

          [registries.private]
          index = "$CARGO_REGISTRY_INDEX"

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

          [source.private]
          registry = "$CARGO_REGISTRY_INDEX"
          EOF

    knowledge:
      - name: private_rust_packages
        contents: |
          Run cargo fetch with CARGO_REGISTRIES_PRIVATE_TOKEN in its environment.
    ```

    レジストリのインデックス URL に認証情報を含めてはいけません。Cargo の `cargo:token` プロバイダーは、指定した名前のレジストリ用トークンを環境変数から読み取ります。ビルドステップで `cargo login` を実行しないでください。

    <Tip>
      crates.io を置き換えずに非公開レジストリを**追加**したいだけの場合は、`[source.crates-io]` と `[source.private]` のセクションを削除し、`cargo install --registry private` を利用するか、`Cargo.toml` に `[dependencies] my-crate = { version = "1.0", registry = "private" }` を記述してください。
    </Tip>
  </Accordion>

  <Accordion title="Ruby / Bundler">
    Ruby をインストールし、非公開の gem サーバーから gem を解決するように Bundler を設定します。

    <Accordion title="必要なシークレット">
      * `GEM_SERVER_URL` — 非公開 gem サーバーの URL (例: `https://artifactory.example.com/artifactory/api/gems/gems-virtual`)
      * `BUNDLE_ARTIFACTORY__EXAMPLE__COM` — `artifactory.example.com` 用の `username:password`。変数名は利用する gem サーバーに合わせて変更してください
    </Accordion>

    ```yaml theme={null}
    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"

    knowledge:
      - name: private_ruby_packages
        contents: |
          Run bundle install with BUNDLE_ARTIFACTORY__EXAMPLE__COM in its environment.
    ```

    認証情報を含まない `GEM_SERVER_URL` を利用してください。Bundler の認証情報用変数では、ホスト名を大文字にしたものに `BUNDLE_` をプレフィックスとして付け、ドットを `__` に、ハイフンを `___` に置き換えます。

    <Tip>
      一般的な gem サーバー URL のパターン:

      * **Artifactory:** `https://artifactory.example.com/artifactory/api/gems/gems-virtual`
      * **Nexus:** `https://nexus.example.com/repository/rubygems-proxy`
      * **Gemfury:** `https://gem.fury.io/<org>`
    </Tip>
  </Accordion>

  <Accordion title="PHP / Composer">
    PHPをインストールし、非公開のPackagistまたはSatisレジストリからパッケージを取得するようにComposerを設定します。

    <Accordion title="必要なシークレット">
      * `COMPOSER_REGISTRY_URL` — 非公開ComposerレジストリのURL (例: `https://repo.packagist.com/<org>`)
      * `COMPOSER_AUTH` — レジストリホスト向けのJSON形式の認証情報。例: `{"http-basic":{"repo.packagist.com":{"username":"<user>","password":"<token>"}}}`
    </Accordion>

    ```yaml theme={null}
    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

          # 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"

    knowledge:
      - name: private_php_packages
        contents: |
          Run composer install with COMPOSER_AUTH in its environment.
          Do not save these credentials to auth.json.
    ```

    認証情報を含まない `COMPOSER_REGISTRY_URL` を利用します。

    <Tip>
      一般的な Composer レジストリ URL のパターン:

      * **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`
    </Tip>
  </Accordion>

  <Accordion title="AWS CodeArtifact トークンの更新">
    AWS CodeArtifact のトークンは通常 12 時間で有効期限が切れます。リテラル参照を含むスクリプトを作成し、npm、pip、Maven を実行するのと同じシェルコマンド内で明示的に source してトークンを取得してください。スクリプトをブループリントに保存しても、セッション開始時に実行されるわけではありません。

    <Info>
      Devin のベースイメージには **`awscli` がプリインストール** されています。設定が必要なのはトークンの更新とレジストリの構成だけです。
    </Info>

    <Accordion title="必要なシークレット">
      * `AWS_ACCESS_KEY_ID` と `AWS_SECRET_ACCESS_KEY` — `codeartifact:GetAuthorizationToken` および `sts:GetServiceBearerToken` 権限を持つ IAM 認証情報
      * `CA_DOMAIN` — CodeArtifact のドメイン名
      * `CA_DOMAIN_OWNER` — ドメインを所有する AWS アカウント ID
      * `CA_REGION` — AWS リージョン (例: `us-east-1`)
      * `CA_NPM_REPO`、`CA_PYPI_REPO`、`CA_MAVEN_REPO` — 各エコシステムのリポジトリ名
    </Accordion>

    ```yaml theme={null}
    maintenance:
      - name: Configure CodeArtifact clients and refresh script
        run: |
          mkdir -p ~/.config
          cat > ~/.config/codeartifact.sh <<'SCRIPT'
          CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \
            --domain "$CA_DOMAIN" \
            --domain-owner "$CA_DOMAIN_OWNER" \
            --region "$CA_REGION" \
            --query authorizationToken \
            --output text) || return
          export CODEARTIFACT_AUTH_TOKEN
          export CA_ENDPOINT="https://${CA_DOMAIN}-${CA_DOMAIN_OWNER}.d.codeartifact.${CA_REGION}.amazonaws.com"
          export PIP_INDEX_URL="https://aws:${CODEARTIFACT_AUTH_TOKEN}@${CA_DOMAIN}-${CA_DOMAIN_OWNER}.d.codeartifact.${CA_REGION}.amazonaws.com/pypi/${CA_PYPI_REPO}/simple/"
          SCRIPT

          # 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}'

          # Maven を設定（任意）
          mkdir -p ~/.m2
          cat > ~/.m2/settings.xml <<'EOF'
          <settings>
            <servers>
              <server>
                <id>codeartifact</id>
                <username>aws</username>
                <password>${env.CODEARTIFACT_AUTH_TOKEN}</password>
              </server>
            </servers>
            <mirrors>
              <mirror>
                <id>codeartifact</id>
                <mirrorOf>*</mirrorOf>
                <url>${env.CA_ENDPOINT}/maven/${env.CA_MAVEN_REPO}/</url>
              </mirror>
            </mirrors>
          </settings>
          EOF

    knowledge:
      - name: codeartifact_packages
        contents: |
          With AWS credentials and the CA_* variables available, run the appropriate
          command in one shell; source the script again for later invocations:
            source ~/.config/codeartifact.sh && npm install
            source ~/.config/codeartifact.sh && pip install -r requirements.txt
            source ~/.config/codeartifact.sh && mvn dependency:resolve
    ```

    スナップショット内で依存関係のキャッシュをウォームアップするには、適切な `source ... &&` コマンドを後続のビルドステップとして追加してください。取得したトークンはそのシェルの環境内にのみ保持されます。`aws codeartifact login`、展開済みトークンを使った `npm config set`、認証情報を含む `pip.conf` などで永続化しないでください。
  </Accordion>
</AccordionGroup>

***

<div id="enterprise-infrastructure">
  ## Enterprise インフラストラクチャ
</div>

すべての org と repo に共通して適用されるマシンレベルのインフラストラクチャです。これらは **Settings > Devin's base environment** (enterprise-wide の場合) または **Settings > Environment > Blueprints > Org-wide setup** (org-wide の場合) で設定します。

<div id="network-and-connectivity">
  ### ネットワークと接続
</div>

<AccordionGroup>
  <Accordion title="社内CA証明書">
    お使いの組織では、内部サービス向けに非公開の認証局を利用しています。Devin が HTTPS 経由で内部レジストリやツールに接続するには、ルート証明書が必要です。

    <Accordion title="必要なシークレット">
      * `CORP_ROOT_CA_B64` — 社内 CA の PEM 証明書を Base64 エンコードしたもの。生成方法: `cat corp-root-ca.crt | base64 -w0`
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Install corporate CA certificate
        run: |
          set -o pipefail
          printf '%s' "$CORP_ROOT_CA_B64" | base64 -d | openssl x509 -outform PEM \
            | 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
    ```

    これらの入力は公開証明書です。`openssl x509` は解析済みの証明書のみを書き出すため、誤って含まれた秘密鍵がトラストストアにコピーされることはありません。各CA証明書は、次の使用例のように個別に指定してください。
  </Accordion>

  <Accordion title="複数のCA証明書">
    組織で複数のCA証明書 (例：内部サービスごとに異なるCA) を利用している場合。

    <Accordion title="必要なシークレット">
      * `CORP_ROOT_CA_B64` — Base64エンコードされたプライマリCA証明書
      * `CORP_INTERMEDIATE_CA_B64` — Base64エンコードされた中間CA証明書
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Install corporate CA certificates
        run: |
          set -o pipefail
          printf '%s' "$CORP_ROOT_CA_B64" | base64 -d | openssl x509 -outform PEM \
            | sudo tee /usr/local/share/ca-certificates/corp-root-ca.crt > /dev/null
          printf '%s' "$CORP_INTERMEDIATE_CA_B64" | base64 -d | openssl x509 -outform PEM \
            | sudo tee /usr/local/share/ca-certificates/corp-intermediate-ca.crt > /dev/null
          sudo update-ca-certificates

          # 単一の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
    ```
  </Accordion>

  <Accordion title="HTTP/HTTPS プロキシ">
    すべてのネットワークトラフィックを社内プロキシ経由で送信します。

    <Accordion title="必要なシークレット">
      * `CORP_HTTP_PROXY` — HTTP プロキシ URL (例: `http://proxy.corp.example.com:8080`)
      * `CORP_HTTPS_PROXY` — HTTPS プロキシ URL
      * `CORP_NO_PROXY` — プロキシを経由しないホストのカンマ区切りリスト (例: `localhost,127.0.0.1,.corp.example.com`)
    </Accordion>

    ```yaml theme={null}
    initialize:
      - 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

    knowledge:
      - name: proxy_commands
        contents: |
          With CORP_HTTP_PROXY, CORP_HTTPS_PROXY and CORP_NO_PROXY available, source
          the proxy setup in each command that needs it, for example:
            source /etc/profile.d/proxy.sh && npm install
            source /etc/profile.d/proxy.sh && git fetch
    ```
  </Accordion>

  <Accordion title="認証付きプロキシ">
    企業内プロキシでユーザー名/パスワード認証が必要な場合。

    <Accordion title="必要なシークレット">
      * `PROXY_USER` — プロキシのユーザー名
      * `PROXY_PASS` — プロキシのパスワード
      * `PROXY_HOST` — プロキシのホスト名とポート (例: `proxy.corp.example.com:8080`)
      * `CORP_NO_PROXY` — プロキシを経由しないホスト
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Configure authenticated proxy
        run: |
          cat <<'PROXY' | sudo tee /etc/profile.d/proxy.sh > /dev/null
          export http_proxy="http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}"
          export https_proxy="$http_proxy"
          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

    knowledge:
      - name: authenticated_proxy_commands
        contents: |
          With the proxy secrets available, source the proxy setup in the same
          command as each tool that needs it, for example:
            source /etc/profile.d/proxy.sh && git fetch
    ```

    プロキシのユーザー名とパスワードに含まれる特殊文字はパーセントエンコードしてください。Git と npm はプロキシの環境変数を利用できます。認証情報を含むプロキシ URL を、これらの永続的な設定にコピーしないでください。
  </Accordion>

  <Accordion title="CA証明書 + プロキシ（併用）">
    社内CAとプロキシの両方が必要な環境向けの設定です。これは、内部サービスが社内証明書を利用し、すべてのトラフィックをプロキシ経由にする必要があるEnterprise環境で一般的です。

    <Accordion title="必要なシークレット">
      * `CORP_ROOT_CA_B64` — Base64エンコードされた社内CA証明書
      * `CORP_HTTP_PROXY`, `CORP_HTTPS_PROXY` — プロキシURL
      * `CORP_NO_PROXY` — プロキシをバイパスするホスト
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Install corporate CA certificate
        run: |
          set -o pipefail
          printf '%s' "$CORP_ROOT_CA_B64" | base64 -d | openssl x509 -outform PEM \
            | 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

    knowledge:
      - name: proxy_commands
        contents: |
          With the proxy secrets available, run:
            source /etc/profile.d/proxy.sh && git fetch
    ```
  </Accordion>

  <Accordion title="VPN接続">
    非公開レジストリ、Git サーバー、その他の社内サービスには、VPN 経由でのみアクセスできます。VPN クライアントはブループリントでインストールしてください。トンネルは必要な操作のために明示的に確立し、終了後は切断して認証情報ファイルを削除してください。

    <Accordion title="必要なシークレット">
      **OpenVPN:**

      * `VPN_CONFIG_B64` — Base64 エンコードされた OpenVPN 設定ファイル (`.ovpn`) 。生成方法: `cat corp.ovpn | base64 -w0`
      * `VPN_AUTH_USER` *(任意)* — VPN でユーザー名/パスワード認証が必要な場合の VPN ユーザー名
      * `VPN_AUTH_PASS` *(任意)* — VPN パスワード

      **WireGuard:**

      * `WG_CONFIG_B64` — Base64 エンコードされた WireGuard 設定ファイル。生成方法: `cat wg0.conf | base64 -w0`
    </Accordion>

    **OpenVPN:**

    ```yaml theme={null}
    initialize:
      - name: Install OpenVPN
        run: |
          sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openvpn
    ```

    このブロックは、VPN のシークレットが利用できるセッション内で明示的に実行してください。`curl` コマンドは、トンネルを必要とする実際の作業に置き換えてください。設定には必要な証明書とキーをインラインで含め、`dev tun0` を利用する必要があります。永続的な VPN サービスは有効化しないでください。

    ```bash theme={null}
    (
      set -euo pipefail
      umask 077
      VPN_DIR=$(mktemp -d)
      cleanup() {
        if [ -f "$VPN_DIR/openvpn.pid" ]; then
          sudo kill "$(cat "$VPN_DIR/openvpn.pid")" || true
        fi
        sudo rm -rf "$VPN_DIR"
      }
      trap cleanup EXIT
      printf '%s' "$VPN_CONFIG_B64" | base64 -d > "$VPN_DIR/corp.conf"
      if [ -n "${VPN_AUTH_USER:-}" ] && [ -n "${VPN_AUTH_PASS:-}" ]; then
        printf '%s\n%s\n' "$VPN_AUTH_USER" "$VPN_AUTH_PASS" > "$VPN_DIR/auth.txt"
        printf 'auth-user-pass %s/auth.txt\n' "$VPN_DIR" >> "$VPN_DIR/corp.conf"
      fi
      sudo openvpn --config "$VPN_DIR/corp.conf" \
        --writepid "$VPN_DIR/openvpn.pid" --daemon
      for i in $(seq 1 30); do
        if ip link show tun0 >/dev/null 2>&1; then break; fi
        sleep 1
      done
      ip link show tun0 >/dev/null
      curl --fail https://service.corp.internal/health
    )
    ```

    **WireGuard:**

    ```yaml theme={null}
    initialize:
      - name: Install WireGuard
        run: |
          sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq wireguard-tools
    ```

    このブロックは `WG_CONFIG_B64` を利用できる状態で明示的に実行し、`curl` コマンドを実際の操作に置き換えてください:

    ```bash theme={null}
    (
      set -euo pipefail
      umask 077
      VPN_DIR=$(mktemp -d)
      cleanup() {
        sudo wg-quick down "$VPN_DIR/corp.conf" || true
        sudo rm -rf "$VPN_DIR"
      }
      trap cleanup EXIT
      printf '%s' "$WG_CONFIG_B64" | base64 -d > "$VPN_DIR/corp.conf"
      sudo wg-quick up "$VPN_DIR/corp.conf"
      curl --fail https://service.corp.internal/health
    )
    ```

    スナップショットのビルドで VPN アクセスが必要な場合は、依存する作業を**すべて**同じ block にまとめ、イメージ化の前にクリーンアップが完了するようにしてください。認証情報の書き込みを `maintenance` に移しただけでは、一時的なものにはなりません。アクティブな tunnel や非公開の VPN 設定をスナップショットに含めないでください。

    <Tip>
      VPN の設定の詳細については、[VPN configuration](/ja/onboard-devin/vpn)を参照してください。
    </Tip>
  </Accordion>

  <Accordion title="カスタムDNS名前解決">
    お客様の内部サービスでは、公開DNSでは名前解決できない非公開DNS名を利用しています。

    ```yaml theme={null}
    initialize:
      - name: Configure custom DNS resolution
        run: |
          # 内部ホスト名を追加する
          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

          # 必要に応じてカスタムネームサーバーを設定する
          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
    ```
  </Accordion>
</AccordionGroup>

<div id="identity-and-security">
  ### アイデンティティとセキュリティ
</div>

<AccordionGroup>
  <Accordion title="GPGコミット署名">
    組織がすべての Git コミットへの署名を必須としており、Devin のコミットを GitHub 上で **Verified** と表示させたい場合の設定です。

    <Accordion title="必要なシークレット">
      * `GPG_PRIVATE_KEY_B64` — Base64 エンコードされた GPG 秘密鍵。生成方法: `gpg --export-secret-keys <key-id> | base64 -w0`
      * `GPG_SIGNING_KEY` — 署名鍵の完全なフィンガープリント
      * `GIT_USER_NAME` — Git の作成者名 (例: `Devin AI`)
      * `GIT_USER_EMAIL` — Git の作成者メールアドレス。**GPG キーの UID と一致している必要があります**。一致しない場合、GitHub は署名を検証しません。
    </Accordion>

    <Note>
      対応する**公開**鍵も、Devin がプッシュに利用する認証情報の GitHub アカウントにアップロードしてください ([GitHub Settings > SSH and GPG keys](https://github.com/settings/keys) から) 。GitHub がコミットを Verified と表示するのは、コミットを作成したアカウントに署名用の公開鍵が登録されている場合のみです。
    </Note>

    スナップショットのビルド中に署名用の秘密鍵をインポートしないでください。目的の変更をステージングしたうえで、対象のシークレットが利用できるセッション内で以下のブロックを明示的に実行します。このブロックは、当該コミットにのみ適用される一時的なキーリングと Git 設定を利用します。

    ```bash theme={null}
    (
      set -euo pipefail
      umask 077
      GNUPGHOME=$(mktemp -d)
      export GNUPGHOME
      trap 'gpgconf --kill gpg-agent; rm -rf "$GNUPGHOME"' EXIT
      printf '%s' "$GPG_PRIVATE_KEY_B64" | base64 -d | gpg --batch --import
      git -c user.name="$GIT_USER_NAME" -c user.email="$GIT_USER_EMAIL" \
        -c user.signingkey="$GPG_SIGNING_KEY" -c commit.gpgsign=true \
        -c gpg.program=gpg commit -m "Describe the change"
    )
    ```

    キーにパスフレーズが必要な場合は、操作中に承認済みの GPG エージェント/pinentry のフローを完了してください。パスフレーズやキーリングをブループリントやスナップショットに保存しないでください。以降のコミットや署名付きタグでも、一時キーリングのセットアップを都度繰り返してください。
  </Accordion>

  <Accordion title="Git アイデンティティと SSH キー">
    非公開の Git サーバーにアクセスするために、Devin の Git アイデンティティと SSH キーを設定します。

    対応している Git プロバイダーでは [Git integrations](/ja/integrations/overview) の利用を推奨します。明示的な SSH キーが必要なサーバーの場合は、秘密鍵をブループリントのビルドに含めず、以下のセッション操作でのみ利用してください。

    <Accordion title="必要なシークレット">
      * `GIT_USER_NAME` — Git の作成者名
      * `GIT_USER_EMAIL` — Git の作成者メールアドレス
      * `SSH_PRIVATE_KEY_B64` — Base64 エンコードされた SSH 秘密鍵。生成方法: `cat ~/.ssh/id_ed25519 | base64 -w0`
      * `SSH_KNOWN_HOSTS_B64` — Base64 エンコードされた known hosts の項目。サーバー管理者が公開しているホストキーのフィンガープリントと照合して検証済みのもの
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Configure git identity
        run: |
          git config --global user.name "$GIT_USER_NAME"
          git config --global user.email "$GIT_USER_EMAIL"
    ```

    このブロックはセッション内で明示的に実行し、Git URL を自組織のサーバーとリポジトリに置き換えてください。

    ```bash theme={null}
    (
      set -euo pipefail
      umask 077
      SSH_DIR=$(mktemp -d)
      trap 'rm -rf "$SSH_DIR"' EXIT
      printf '%s' "$SSH_PRIVATE_KEY_B64" | base64 -d > "$SSH_DIR/id_ed25519"
      printf '%s' "$SSH_KNOWN_HOSTS_B64" | base64 -d > "$SSH_DIR/known_hosts"
      export GIT_SSH_COMMAND="ssh -F /dev/null -i '$SSH_DIR/id_ed25519' -o IdentitiesOnly=yes -o UserKnownHostsFile='$SSH_DIR/known_hosts' -o StrictHostKeyChecking=yes"
      git ls-remote git@git.corp.internal:team/repo.git
    )
    ```

    <Tip>
      独自の SSH オプションが必要な場合は、永続的な SSH 設定やホームディレクトリに秘密鍵をコピーせず、この実行時に追加してください。操作ごとにセットアップを繰り返してください。
    </Tip>
  </Accordion>
</AccordionGroup>

<div id="system-configuration">
  ### システム構成
</div>

<AccordionGroup>
  <Accordion title="システムパッケージ">
    Devinのデフォルトイメージに含まれていないシステムレベルのパッケージ (例：画像処理やPDF生成に必要なネイティブライブラリ) をインストールします。

    ```yaml theme={null}
    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
    ```
  </Accordion>

  <Accordion title="カスタム環境変数">
    すべてのセッションで利用できる永続的な、機密でない環境変数を設定します。シークレットの値やそこから派生した認証情報を `$ENVRC` に書き込まないでください。

    推奨される方法は、`KEY=VALUE` 形式の行を `$ENVRC` ファイルに書き込むことです。`$ENVRC` に書き込まれた変数は、以降のすべてのステップと Devin セッションで自動的にエクスポートされます (GitHub Actions の `$GITHUB_ENV` と同様です) 。

    ```yaml theme={null}
    initialize:
      - name: カスタム環境変数を設定する
        run: |
          echo "CORPORATE_ENV=production" >> $ENVRC
          echo "DEFAULT_REGION=us-east-1" >> $ENVRC
          echo "MAX_RETRIES=3" >> $ENVRC
    ```

    <Tip>
      システム全体で利用できるように、環境変数を `/etc/profile.d/` のスクリプトに書き込むこともできます。

      ```bash theme={null}
      cat << 'ENVVARS' | sudo tee /etc/profile.d/custom-env.sh > /dev/null
      export CORPORATE_ENV=production
      export DEFAULT_REGION=us-east-1
      ENVVARS
      ```

      どちらの方法でも問題ありません。ほとんどの場合は、`$ENVRC` のほうが簡単でおすすめです。
    </Tip>
  </Accordion>

  <Accordion title="ロケールとタイムゾーン">
    デフォルトのベースイメージでは、ロケール設定が正しくない場合があります。ビルドツール、Java、Python、Git で警告が表示されないように、ロケールとタイムゾーンを設定してください。

    ```yaml theme={null}
    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

          # ロケールを生成して設定する
          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

          # タイムゾーンを設定する
          sudo timedatectl set-timezone UTC 2>/dev/null || \
            sudo ln -sfn /usr/share/zoneinfo/UTC /etc/localtime
    ```
  </Accordion>

  <Accordion title="リソース制限（ulimits）">
    Java、Gradle、Node.js のビルドでは、デフォルトの 1024 のオープンファイル上限に頻繁に達します。ビルドの失敗を防ぐため、この上限を引き上げてください。

    ```yaml theme={null}
    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

          # カーネルの最大値も設定する
          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
    ```
  </Accordion>

  <Accordion title="APTミラーの変更">
    air-gapped または制限された環境では、デフォルトの Ubuntu APT ソースを内部ミラーに置き換えます。

    <Accordion title="必要なシークレット">
      * `APT_MIRROR_URL` — 内部 APT ミラーの URL (例: `https://artifactory.example.com/artifactory/ubuntu-remote`)
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Replace APT sources with internal mirror
        run: |
          # 元のソースをバックアップ
          sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

          # すべてのUbuntuミラーを内部ミラーに置き換える
          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
    ```

    <Tip>
      一般的なAPTミラーのURLパターン:

      * **Artifactory:** `https://artifactory.example.com/artifactory/ubuntu-remote`
      * **Nexus:** `https://nexus.example.com/repository/ubuntu-proxy`
    </Tip>
  </Accordion>
</AccordionGroup>

***

<div id="advanced-patterns">
  ## 高度なパターン
</div>

<AccordionGroup>
  <Accordion title="direnv を使った環境変数の管理">
    Devinのベース環境には [direnv](https://direnv.net/) が含まれています。`.envrc` ファイルを作成するには `initialize` を利用します。direnv がそれらを自動的に読み込みます。

    ```yaml theme={null}
    initialize: |
      cat <<'EOF' > .envrc
      export DATABASE_URL=postgresql://localhost:5432/myapp_dev
      export REDIS_URL=redis://localhost:6379
      export APP_ENV=development
      EOF

    maintenance: |
      direnv allow .
    ```

    <Info>
      direnv は Devin のシェルにあらかじめ組み込まれているため、`.envrc` の変数は自動的に読み込まれます。手動で source する必要はありません。
    </Info>

    <Tip>
      **機密性の高い**環境変数 (APIキー、トークン、データベースのパスワード) には、`.envrc` ファイルではなく [repo secrets](/ja/product-guides/secrets) を利用し、それらを必要とするセッションのコマンドに明示的にバインドしてください。ビルド中にシークレットを展開してファイルに書き出すと、スナップショットに含まれてしまう可能性があります。
    </Tip>
  </Accordion>

  <Accordion title="リポジトリごとのNodeバージョン切り替え">
    `.nvmrc` を使って、リポジトリごとに Node.js のバージョンを切り替えるには、nvm (プリインストール済み) を利用します。

    ```yaml theme={null}
    initialize: |
      nvm install 18
      nvm install 20
      nvm install 22

    maintenance: |
      nvm use
    ```

    <Info>
      `nvm use` はリポジトリのルートにある `.nvmrc` を読み取ります。リポジトリに `.nvmrc` があることを確認してください (例: `20` を含むもの) 。
    </Info>
  </Accordion>

  <Accordion title="ブラウザでの認証 (Playwright)">
    Devin では、**セッション中** に `localhost:29229` の CDP エンドポイントを備えた Chrome ブラウザを利用できます。Playwright スクリプトを利用して、ブラウザベースのログインを自動化してください。

    <Warning>
      ブラウザを利用できるのはセッション中のみで、スナップショットのビルドでは利用できません。`initialize` で Playwright をインストールし、ログインスクリプトはリポジトリに保存してください。
    </Warning>

    ```yaml theme={null}
    initialize: |
      pip install playwright
      playwright install chromium

    maintenance: |
      npm install

    knowledge:
      - 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
    ```

    ログインスクリプトの例 (`scripts/login.py`) :

    ```python theme={null}
    from playwright.sync_api import sync_playwright
    import os

    with 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")
    ```

    <Warning>
      ログイン認証情報はソースコードに含めず、シークレットとして保存してください。長期間使用する認証が必要な場合は、Devin が自動で再認証できるよう、ログインスクリプトを `.agents/skills/` にコミットしてください。
    </Warning>
  </Accordion>

  <Accordion title="カスタムのシステムツールとPATH">
    `initialize` でシステムパッケージやカスタムバイナリをインストールし、PATH を設定します。

    ```yaml theme={null}
    initialize:
      - name: Install system packages
        run: |
          apt-get update
          apt-get install -y \
            jq \
            ripgrep \
            fd-find \
            protobuf-compiler \
            libssl-dev

      - name: Install custom CLI tool
        run: |
          curl -L https://github.com/example/tool/releases/download/v1.0/tool-linux-amd64 \
            -o /usr/local/bin/mytool
          chmod +x /usr/local/bin/mytool

      - name: Add custom bin directory to PATH
        run: |
          mkdir -p ~/bin
          echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc

    knowledge:
      - name: tools
        contents: |
          Custom tools available:
          - mytool: installed at /usr/local/bin/mytool
          - Additional binaries can be placed in ~/bin
    ```
  </Accordion>

  <Accordion title="ツールセットアップ用のGitHub Actions">
    Devin では、Node.js ベースの GitHub Actions をブループリント内で直接実行できます。これにより、CI で利用しているのと同じアクションを使って、特定のバージョンのツールをインストールできます。

    ```yaml theme={null}
    initialize:
      - name: "Install Node.js 20"
        uses: github.com/actions/setup-node@v4
        with:
          node-version: "20"

      - name: "Install Python 3.12"
        uses: github.com/actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: "Install Go 1.22"
        uses: github.com/actions/setup-go@v5
        with:
          go-version: "1.22"

      - name: "Install Java 21"
        uses: github.com/actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"

      - name: "Install Gradle"
        uses: github.com/gradle/actions/setup-gradle@v4

      - name: "Install Ruby 3.3"
        uses: github.com/ruby/setup-ruby@v1
        with:
          ruby-version: "3.3"

      - name: "Install additional tools"
        run: |
          pip install uv
          npm install -g pnpm turbo
          go install golang.org/x/tools/gopls@latest

    maintenance: |
      echo "All runtimes are available:"
      node --version
      python --version
      go version
      java --version
    ```

    <Info>
      `setup-node` や `setup-python` などのアクションは、PATH と環境変数を変更します。あるアクションでインストールされたバイナリは、後続のすべてのステップと `maintenance` で利用できます。サポートされるのは **Node.js ベースの** GitHub Actions のみです。Composite アクションと Docker ベースのアクションはサポートされていません。
    </Info>

    <Tip>
      基本的なツールのセットアップに GitHub Actions は必要ありません。シェルコマンドを直接実行しても (`nvm install 20`、`curl ... | sh`、`apt-get install`) 、同様に機能し、多くの場合はこちらのほうが簡単です。GitHub Actions が特に有用なのは、CI のセットアップと完全に一致させたい場合や、複数のディストリビューションに対応する `setup-java` のようなアクションの利便性が必要な場合です。
    </Tip>
  </Accordion>

  <Accordion title="複数アプリ向けローカル HTTPS リバースプロキシ">
    `app.example.com`、`api.example.com`、`admin.example.com` のような実在しそうなホスト名で、複数のサービスを HTTPS 経由で公開できます。`initialize` で 1 つのリバースプロキシをインストールし、各ホスト名をそれぞれ異なるローカルのアップストリームポートにルーティングします。

    [Caddy](https://caddyserver.com/) は、ルーティングとローカル TLS を 1 つのツールでまとめて処理します。Caddyfile では各ホスト名をアップストリームに対応付け、`tls internal` は Caddy に組み込まれた CA から、ホスト名ごとに信頼された証明書を自動発行します。`caddy trust` はその CA ルートをシステムの信頼ストアにインストールし、同じルートを NSS データベースにも追加すると、ブラウザでも受け入れられるようになります。

    Caddyfile はブループリントエディタの **File attachments** セクションからアップロードしてください。アップロードすると、`$FILE_CADDYFILE` として利用できるようになります。

    ```caddyfile Caddyfile theme={null}
    app.example.com {
      tls internal
      reverse_proxy 127.0.0.1:3000
    }

    api.example.com {
      tls internal
      reverse_proxy 127.0.0.1:3001
    }

    admin.example.com {
      tls internal
      reverse_proxy 127.0.0.1:3002
    }
    ```

    ```yaml theme={null}
    initialize:
      - name: Install Caddy and NSS tools
        run: |
          sudo apt-get install -y debian-keyring debian-archive-keyring \
            apt-transport-https curl libnss3-tools
          curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
            | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
          curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
            | sudo tee /etc/apt/sources.list.d/caddy-stable.list
          sudo apt-get update -qq
          sudo apt-get install -y caddy

      - name: Install Caddyfile, hosts entries, and trust internal CA
        run: |
          sudo install -m 0644 "$FILE_CADDYFILE" /etc/caddy/Caddyfile

          for host in app.example.com api.example.com admin.example.com; do
            grep -q " $host$" /etc/hosts \
              || echo "127.0.0.1 $host" | sudo tee -a /etc/hosts > /dev/null
          done

          sudo systemctl enable --now caddy
          sudo caddy trust

          mkdir -p ~/.pki/nssdb
          [ -f ~/.pki/nssdb/cert9.db ] \
            || certutil -d sql:$HOME/.pki/nssdb -N --empty-password

          CADDY_ROOT=/var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt
          for _ in $(seq 1 30); do
            sudo test -f "$CADDY_ROOT" && break
            sleep 1
          done

          if sudo test -f "$CADDY_ROOT" \
             && ! certutil -d sql:$HOME/.pki/nssdb -L | grep -q "Caddy Local Authority"; then
            sudo install -o "$USER" -m 0644 "$CADDY_ROOT" /tmp/caddy-root.crt
            certutil -d sql:$HOME/.pki/nssdb -A -t "C,," \
              -n "Caddy Local Authority" -i /tmp/caddy-root.crt
            rm -f /tmp/caddy-root.crt
          fi
    ```

    <Info>
      `/etc/hosts` ループによって、セッション内では `app.example.com` が `127.0.0.1` に名前解決されます。Caddyfile に記述する各ホスト名について、`/etc/hosts` ループにもエントリを追加してください。
    </Info>

    <Tip>
      サービスを追加するには、Caddyfile に 3 行のブロックを追記し、`/etc/hosts` ループにエントリを 1 つ追加してから、そのホスト名に HTTPS でアクセスしてください。Caddy は最初のリクエスト時に証明書を発行するため、app ごとに証明書を生成する必要はありません。
    </Tip>
  </Accordion>
</AccordionGroup>

***

<div id="full-stack-examples">
  ## フルスタックの使用例
</div>

これらの使用例では、Enterprise と org レベルの設定がどのように組み合わさるかを示しています。実際には、これらはスコープごとに分けて扱うのが一般的です。ここでは参考用にまとめて示しています。

<AccordionGroup>
  <Accordion title="Enterprise向けのフルスタック（Artifactory）">
    Enterprise環境のフルセット構成例：社内CA証明書、プロキシ、Java (Maven) 、Python (pip/uv) 、Node.js (npm) 、Dockerをすべて単一のArtifactoryインスタンスに向けた設定です。

    <Accordion title="必要なシークレット">
      **ネットワーク & 信頼設定 (アカウント全体) :**

      * `CORP_ROOT_CA_B64` — Base64 エンコードされた社内CA証明書
      * `CORP_HTTP_PROXY` — HTTP プロキシ URL
      * `CORP_HTTPS_PROXY` — HTTPS プロキシ URL
      * `CORP_NO_PROXY` — プロキシをバイパスするホスト

      **レジストリ認証情報 (組織全体) :**

      * `ARTIFACTORY_USER` — Artifactory のユーザー名
      * `ARTIFACTORY_TOKEN` — Artifactory API トークンまたはパスワード
      * `ARTIFACTORY_MAVEN_URL` — Maven リポジトリ URL (例: `https://artifactory.example.com/artifactory/maven-virtual`)
      * `ARTIFACTORY_PYPI_URL` — PyPI リポジトリ URL (例: `https://user:token@artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple`)
      * `ARTIFACTORY_NPM_URL` — npm リポジトリ URL (例: `https://artifactory.example.com/artifactory/api/npm/npm-virtual`)
      * `ARTIFACTORY_DOCKER_URL` — Docker レジストリ URL (例: `artifactory.example.com`)
    </Accordion>

    これは通常、3つのスコープに分割されます：

    * **アカウント全体で共通 (`initialize`) :** 証明書とプロキシ
    * **組織全体 (`initialize`):** 言語ランタイムのインストール
    * **組織全体 (`maintenance`):** リテラル参照を含むレジストリ設定
    * **セッションコマンド:** シークレットを明示的に指定し、環境設定を source で読み込み、個々の Docker 操作ごとにログインする

    参考までに、まとめて示します：

    ```yaml theme={null}
    initialize:
      # ── アカウント全体：ネットワークと信頼 ──────────────────────────────────────

      - name: Install corporate CA certificate
        run: |
          set -o pipefail
          printf '%s' "$CORP_ROOT_CA_B64" | base64 -d | openssl x509 -outform PEM \
            | 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

      # ── Org全体：言語ランタイム ──────────────────────────────────────────

      - name: Install JDK 17 + Maven
        run: |
          set -o pipefail
          source /etc/profile.d/proxy.sh
          sudo --preserve-env=http_proxy,https_proxy,no_proxy,HTTP_PROXY,HTTPS_PROXY,NO_PROXY \
            apt-get update -qq
          sudo --preserve-env=http_proxy,https_proxy,no_proxy,HTTP_PROXY,HTTPS_PROXY,NO_PROXY \
            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: |
          set -o pipefail
          source /etc/profile.d/proxy.sh
          curl -LsSf https://astral.sh/uv/install.sh | sh

    maintenance:
      # ── Org全体：レジストリ設定 ───────────────────────────────────

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

      - name: Configure pip/uv → Artifactory PyPI
        run: |
          mkdir -p ~/.config
          cat > ~/.config/private-pypi.sh <<'EOF'
          export PIP_INDEX_URL="$ARTIFACTORY_PYPI_URL"
          export UV_INDEX_URL="$ARTIFACTORY_PYPI_URL"
          EOF

      - 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}'

    knowledge:
      - name: private_packages
        contents: |
          With the corresponding secrets available, source setup in each command:
            source /etc/profile.d/proxy.sh && mvn dependency:resolve
            source /etc/profile.d/proxy.sh && npm install
            source /etc/profile.d/proxy.sh && source ~/.config/private-pypi.sh && uv sync
      - name: private_container_images
        contents: |
          With the Artifactory and proxy secrets available, run in one shell.
          Replace team/image:tag with the image to pull:
            (
              set -euo pipefail
              umask 077
              source /etc/profile.d/proxy.sh
              DOCKER_CONFIG=$(mktemp -d)
              export DOCKER_CONFIG
              trap 'rm -rf "$DOCKER_CONFIG"' EXIT
              printf '%s' "$ARTIFACTORY_TOKEN" |
                docker login "$ARTIFACTORY_DOCKER_URL" \
                  --username "$ARTIFACTORY_USER" --password-stdin
              docker pull "$ARTIFACTORY_DOCKER_URL/team/image:tag"
            )
    ```

    <Info>
      この例では、すべてのレジストリが同じ Artifactory インスタンスを参照していますが、URL パスはそれぞれ異なります。各パッケージエコシステムには、それぞれ固有のエンドポイント形式があります。Maven、PyPI、npm、Docker の URL は、同じレジストリであってもそれぞれ異なります。
    </Info>
  </Accordion>

  <Accordion title="異なるレジストリを利用する多言語構成">
    言語ごとに異なる非公開レジストリを利用する場合 (例: Maven は Nexus、npm は GitHub Packages、Python は Artifactory) 。

    <Accordion title="必要なシークレット">
      * `NEXUS_MAVEN_URL` — Nexus Maven リポジトリ URL
      * `NEXUS_USER` — Nexus のユーザー名
      * `NEXUS_PASS` — Nexus のパスワード
      * `GITHUB_PACKAGES_TOKEN` — `read:packages` スコープを持つ GitHub パーソナルアクセストークン
      * `ARTIFACTORY_USER` — Artifactory のユーザー名
      * `ARTIFACTORY_TOKEN` — Artifactory API トークン
    </Accordion>

    Git provider を接続し、[Git integrations](/ja/integrations/overview) を通じて Go モジュールをホストしているリポジトリへのアクセスを与えてください。

    ```yaml theme={null}
    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>${env.NEXUS_MAVEN_URL}</url>
              </mirror>
            </mirrors>
            <servers>
              <server>
                <id>nexus</id>
                <username>${env.NEXUS_USER}</username>
                <password>${env.NEXUS_PASS}</password>
              </server>
            </servers>
          </settings>
          EOF

      # npm → GitHub Packages（スコープ付き）
      - 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
          cat > ~/.config/private-pypi.sh <<'EOF'
          export PIP_INDEX_URL="https://$ARTIFACTORY_USER:$ARTIFACTORY_TOKEN@artifactory.example.com/artifactory/api/pypi/pypi-virtual/simple"
          EOF

      # Go → 接続済みのGitプロバイダー経由の非公開モジュール
      - name: Configure Go private modules
        run: |
          go env -w GOPRIVATE=github.com/myorg/*

    knowledge:
      - name: private_python_packages
        contents: |
          With URL-encoded ARTIFACTORY_USER and ARTIFACTORY_TOKEN available, run:
            source ~/.config/private-pypi.sh && pip install -r requirements.txt
    ```
  </Accordion>

  <Accordion title="非公開ミラー付きエアギャップ環境">
    完全にエアギャップされた環境では、Devin は公開 URL に一切アクセスできません。すべてのツール、ランタイム、パッケージは内部ミラー経由で取得する必要があります。

    <Accordion title="必要なシークレット">
      **証明書:**

      * `CORP_ROOT_CA_B64` — Base64 エンコードされた社内CA証明書

      **ミラーへのアクセス:**

      * `APT_MIRROR_URL` — 内部 Ubuntu APT ミラーの URL
      * `MIRROR_USER` — ミラー認証用のユーザー名
      * `MIRROR_PASS` — ミラー認証用のパスワード
      * `JDK_TARBALL_URL` — 内部ミラーから JDK tarball をダウンロードするための URL
      * `NODE_TARBALL_URL` — 内部ミラーから Node.js tarball をダウンロードするための URL

      **パッケージレジストリ:**

      * `INTERNAL_MAVEN_URL` — 内部 Maven レジストリの URL
      * `INTERNAL_NPM_URL` — 内部 npm レジストリの URL
      * `INTERNAL_PYPI_URL` — 内部 PyPI レジストリの URL
    </Accordion>

    ```yaml theme={null}
    initialize:
      - name: Install corporate CA certificate
        run: |
          set -o pipefail
          printf '%s' "$CORP_ROOT_CA_B64" | base64 -d | openssl x509 -outform PEM \
            | 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: |
          # 内部アーティファクトストアからJDKのtarballをダウンロード
          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>${env.INTERNAL_MAVEN_URL}</url>
              </mirror>
            </mirrors>
            <servers>
              <server>
                <id>internal</id>
                <username>${env.MIRROR_USER}</username>
                <password>${env.MIRROR_PASS}</password>
              </server>
            </servers>
          </settings>
          EOF

          # npm
          npm config set registry '${INTERNAL_NPM_URL}'

          # pip
          mkdir -p ~/.config
          cat > ~/.config/private-pypi.sh <<'EOF'
          export PIP_INDEX_URL="$INTERNAL_PYPI_URL"
          EOF

    knowledge:
      - name: internal_python_packages
        contents: |
          With INTERNAL_PYPI_URL available, run:
            source ~/.config/private-pypi.sh && pip install -r requirements.txt
    ```

    <Warning>
      エアギャップ環境では、Devin が必要とするすべてのツール (言語ランタイム、CLI ツールなど) を社内ミラーで利用できるようにしておく必要があります。公開レジストリやダウンロードサイトにはアクセスできません。
    </Warning>
  </Accordion>

  <Accordion title="VPN + 証明書 + プロキシ + 言語">
    VPNツール、証明書、プロキシ設定、多言語サポートを組み合わせた包括的なエンタープライズ向けセットアップです。ブループリントはツールをインストールし、リテラル参照とともに設定を保存します。内部アクセスが必要な操作を実行する際は、明示的にVPNへ接続してください。

    <Accordion title="必要なシークレット">
      **VPN:**

      * `VPN_CONFIG_B64` — Base64 でエンコードされた OpenVPN 設定ファイル

      **ネットワークと信頼設定:**

      * `CORP_ROOT_CA_B64` — Base64 でエンコードされた社内CA証明書
      * `CORP_HTTP_PROXY` — HTTP プロキシ URL
      * `CORP_HTTPS_PROXY` — HTTPS プロキシ URL
      * `CORP_NO_PROXY` — プロキシを経由しないホスト

      **レジストリ認証情報:**

      * `MAVEN_REGISTRY_URL` — Maven レジストリ URL
      * `NPM_REGISTRY_URL` — npm レジストリ URL
      * `PYPI_REGISTRY_HOST` — PyPI レジストリのホスト名
      * `REGISTRY_USER` — レジストリのユーザー名 (Maven と pip 用)
      * `REGISTRY_PASS` — レジストリのパスワード (Maven と pip 用)
      * `REGISTRY_TOKEN` — npm 認証トークン
    </Accordion>

    ```yaml theme={null}
    initialize:
      # 1. VPNクライアント
      - name: Install VPN client
        run: |
          sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
          sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openvpn

      # 2. DNS — 内部ホスト名を解決する
      - 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. 証明書 — 内部CAを信頼する
      - name: Install CA certificate
        run: |
          set -o pipefail
          printf '%s' "$CORP_ROOT_CA_B64" | base64 -d | openssl x509 -outform PEM \
            | 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. プロキシ — 社内プロキシ経由でトラフィックをルーティングする
      - 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. 言語ランタイム
      - name: Install language runtimes over VPN
        run: |
          (
            set -euo pipefail
            umask 077
            VPN_DIR=$(mktemp -d)
            cleanup() {
              if [ -f "$VPN_DIR/openvpn.pid" ]; then
                sudo kill "$(cat "$VPN_DIR/openvpn.pid")" || true
              fi
              sudo rm -rf "$VPN_DIR"
            }
            trap cleanup EXIT
            printf '%s' "$VPN_CONFIG_B64" | base64 -d > "$VPN_DIR/corp.conf"
            sudo openvpn --config "$VPN_DIR/corp.conf" \
              --writepid "$VPN_DIR/openvpn.pid" --daemon
            for i in $(seq 1 30); do
              if ip link show tun0 >/dev/null 2>&1; then break; fi
              sleep 1
            done
            ip link show tun0 >/dev/null
            source /etc/profile.d/proxy.sh
            sudo --preserve-env=http_proxy,https_proxy,no_proxy,HTTP_PROXY,HTTPS_PROXY,NO_PROXY \
              apt-get update -qq
            sudo --preserve-env=http_proxy,https_proxy,no_proxy,HTTP_PROXY,HTTPS_PROXY,NO_PROXY \
              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
            npm install -g pnpm
            curl -LsSf https://astral.sh/uv/install.sh | sh
          )

    maintenance:
      - name: Configure Maven
        run: |
          mkdir -p ~/.m2
          cat > ~/.m2/settings.xml <<'EOF'
          <settings>
            <mirrors>
              <mirror>
                <id>corp</id>
                <mirrorOf>*</mirrorOf>
                <url>${env.MAVEN_REGISTRY_URL}</url>
              </mirror>
            </mirrors>
            <servers>
              <server>
                <id>corp</id>
                <username>${env.REGISTRY_USER}</username>
                <password>${env.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
          cat > ~/.config/private-pypi.sh <<'EOF'
          export PIP_INDEX_URL="https://$REGISTRY_USER:$REGISTRY_PASS@${PYPI_REGISTRY_HOST}/simple"
          export UV_INDEX_URL="$PIP_INDEX_URL"
          EOF

    knowledge:
      - name: internal_packages
        contents: |
          Use the temporary OpenVPN setup/cleanup block from the template library
          when an operation needs VPN access. Inside that block, with the registry
          and proxy secrets available, replace the sample curl command with:
            source /etc/profile.d/proxy.sh
            mvn dependency:resolve
            npm install
            source ~/.config/private-pypi.sh
            uv sync
          Percent-encode the pip URL credentials. Disconnect the VPN and remove its
          temporary files when the operation finishes.
    ```

    <Info>
      **ブートストラップアクセスが必要です。** トンネルを接続する前に、OpenVPN クライアントがプリインストールされているか、インストール可能である必要があります。`VPN_CONFIG_B64` にはインラインの証明書/キーを含め、`dev tun0` を利用し、対話的な認証なしで接続できる必要があります。ランタイムのダウンロードは 1 つのトンネルライフサイクル内で実行され、プロキシ環境を明示的に読み込みます。セッションでの操作については、[ネットワークと接続性](#network-and-connectivity) にある VPN のセットアップ/クリーンアップブロックを繰り返してください。ブループリントはセッション開始時に VPN を再接続しません。
    </Info>
  </Accordion>
</AccordionGroup>

***

<div id="tips-for-writing-good-blueprints">
  ## 良い ブループリント を書くためのヒント
</div>

* **まずセッションでコマンドをテストする。** ブループリント に追加する前に、Devin のセッションでコマンドを手動で実行してください。フルビルドを待つより、そのほうが速く済みます。
* **一度だけインストールするツールには `initialize`、依存関係には `maintenance` を利用する。** インストールに数分かかるもの (コンパイラ、大きなバイナリ、グローバルツール) は `initialize` に入れます。短時間で終わる依存関係コマンド (`npm install`、`uv sync`) は `maintenance` に入れます。
* **`maintenance` コマンドは高速に保つ。** 2 分以内を目安にしてください。これらはビルド中に実行され、セッション開始時にエージェントに提示されます。
* **シークレット以外の環境変数には `$ENVRC` を利用する。** 認証情報や、そこから 由来 する トークン を `$ENVRC`、`.bashrc`、`.profile` に書き込まないでください。シークレット に依存するシェル設定は、それを必要とするコマンド内で明示的に読み込んでください。
* **ステップには名前を付ける。** `name` フィールドを使う expanded form にすると、ビルドログ内の失敗箇所を特定しやすくなります。
* **モノレポ では サブシェル を利用する。** `(cd packages/foo && npm install)` は サブシェル 内で実行されるため、後続のステップはディレクトリ変更の影響を受けません。
* **`npm ci` ではなく `npm install` を利用する。** `npm ci` は `node_modules` を削除し、ゼロから再インストールするため、`maintenance` には不向きです。
* **機密性の高い値には repo secrets を利用する。** ブループリント に直接書き込むのではなく、リポジトリのブループリントエディタの **Secrets** タブで設定してください。

構文の詳細については、[Blueprint reference](/ja/onboard-devin/environment/blueprint-reference) を参照してください。ビルド失敗のトラブルシューティングについては、[Declarative configuration > Troubleshooting](/ja/onboard-devin/environment/blueprints#troubleshooting-builds) を参照してください。
