适用于常见语言和使用场景的可直接复制粘贴蓝图。每个模板都可独立使用。组合使用即可构建完整配置。
如需查看每个字段的完整说明,请参阅 蓝图参考。
Secrets: 模板使用 $SECRET_NAME 引用 secrets。使用模板前,请先在 Settings > Secrets 中配置好这些 secrets。切勿在蓝图中硬编码凭据。
适用于最常见配置的精简蓝图。复制其中一个,粘贴到蓝图编辑器中即可。
initialize: |
npm install -g pnpm
maintenance: |
pnpm install
knowledge:
- name: lint
contents: |
运行 `pnpm lint` 检查错误。
- name: test
contents: |
运行 `pnpm test` 执行完整测试套件。
initialize: |
curl -LsSf https://astral.sh/uv/install.sh | sh
maintenance: |
uv sync
knowledge:
- name: lint
contents: |
运行 `uv run ruff check .` 进行 lint 检查。
- name: test
contents: |
运行 `uv run pytest` 执行完整测试套件。
initialize:
- name: Install pnpm
run: npm install -g pnpm
- name: Install 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
按仓库设置的构建步骤、依赖管理和 Knowledge 条目。请在 Settings > Environment configuration > [你的仓库] 中进行设置。
适用于使用 uv 进行依赖管理的 Python 项目的推荐设置。initialize: |
curl -LsSf https://astral.sh/uv/install.sh | sh
maintenance: |
uv sync
knowledge:
- name: lint
contents: |
uv run ruff check .
Auto-fix:
uv run ruff check --fix .
- name: test
contents: |
uv run pytest
- name: build
contents: |
uv run python -m build
使用 pip 和 venv 的传统 Python 设置。项目依赖 requirements.txt 时请使用此配置。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
使用 npm 的标准 Node.js 配置。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
在 maintenance 中使用 npm install (不要用 npm ci) 。前者会执行增量更新,而 npm ci 会在每个会话中删除 node_modules,并从头重新安装。
适用于使用 pnpm 的项目。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
标准 Go 模块配置。
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 ./...
使用 Gradle 配置 Java 环境。JDK 17 已预装在 Devin 的基础镜像中。如果默认的 OpenJDK 17 已满足需求,可跳过 JDK 安装步骤。
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
使用 Maven 配置 Java 环境。JDK 17 已预装在 Devin 的基础镜像中。如果默认的 OpenJDK 17 已满足需求,可跳过 JDK 安装步骤。
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
基于 PostgreSQL 的 Rails 配置。
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
使用 cargo 的标准 Rust 配置。
Rust (通过 rustup) 和 Cargo已预装在 Devin 的基础镜像中。如果默认的稳定工具链已能满足需求,请跳过安装步骤。你只需拉取依赖。
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
包含 Node.js 前端和 Python 后端的 Monorepo。每个子项目都有各自的 knowledge 条目。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: |
这是一个包含三个软件包的 monorepo:
- `packages/frontend` — React 应用(TypeScript、pnpm)
- `packages/backend` — Python API(FastAPI、uv)
- `packages/shared` — 共享 TypeScript 工具库(必须先于前端构建)
- name: frontend
contents: |
运行 `cd packages/frontend && pnpm dev` 启动开发服务器。
运行 `cd packages/frontend && pnpm lint` 执行 lint 检查。
运行 `cd packages/frontend && pnpm test` 运行测试。
- name: backend
contents: |
运行 `cd packages/backend && uv run uvicorn app.main:app --reload` 启动 API。
运行 `cd packages/backend && uv run ruff check .` 执行 lint 检查。
运行 `cd packages/backend && uv run pytest` 运行测试。
使用 subshell (cd dir && command),不要使用 cd dir && command,这样每个步骤之间都会重置工作目录。
一个 Java Monorepo,其中不同服务需要不同的 JDK 版本。在设置时安装两个 JDK,然后使用 knowledge 条目告诉 Devin 每个服务应使用哪个 JAVA_HOME。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: |
构建 legacy 服务(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)
将包管理器配置为从私有注册表解析依赖。在 设置 > 环境配置 > 组织范围设置 中进行设置 (如果只有一个 仓库 需要,则可按 仓库 单独设置) 。
凭据配置应放在 maintenance 中,而不是 initialize 中。 将 secrets (注册表密码、身份验证令牌) 写入配置文件的步骤应使用 maintenance,这样每个 session 都会重新加载最新凭据。
secrets 会在保存快照前被移除,因此在 initialize 期间写入的配置文件,在 sessions 启动时将不包含有效凭据。
如果你的私有注册表使用 corporate CA,请先确保已在企业级别安装 CA 证书。以下配置假定 HTTPS 信任
已经建立。
npm(作用域)
npm(完整镜像)
pnpm
Yarn
将 npm 配置为从私有 registry 解析带作用域的软件包 (例如 @myorg/*) ,同时公开软件包仍从默认的 npm registry 获取。
- GITHUB_PACKAGES_TOKEN — 具有 read:packages 作用域的 Personal access token 或 GitHub App 令牌
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
将 @myorg 替换为你的 npm 作用域。常见的私有 registry 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>
让所有 npm 软件包都通过你的私有 registry (而不仅仅是带作用域的软件包) 。
NPM_REGISTRY_URL — 你的 npm registry 的完整 URL (例如 https://artifactory.example.com/artifactory/api/npm/npm-virtual) - NPM_REGISTRY_HOST — 仅主机名,不含协议 (例如
artifactory.example.com) - REGISTRY_TOKEN — 该 registry 的 npm 身份验证令牌
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
将 pnpm 配置为从私有 registry 解析软件包。
NPM_REGISTRY_URL — 你的 npm registry 的完整 URL - NPM_REGISTRY_HOST — 仅主机名,不含协议 - REGISTRY_TOKEN — 该 registry 的 npm 身份验证令牌
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
将 Yarn (Classic v1 或 Berry v2+) 配置为从私有 registry 解析软件包。
- NPM_REGISTRY_URL — 你的 npm/Yarn registry 的完整 URL - REGISTRY_TOKEN — 该 registry 的身份验证令牌 (仅 Berry)
Yarn Classic (v1) :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"
# 对于带作用域的软件包:
# yarn config set @myorg:registry "https://npm.pkg.github.com"
Yarn Berry (v2+) :maintenance:
- name: Configure Yarn Berry for private registry
run: |
yarn config set npmRegistryServer "$NPM_REGISTRY_URL"
yarn config set npmAuthToken "$REGISTRY_TOKEN"
# 对于带作用域的软件包:
# yarn config set npmScopes.myorg.npmRegistryServer "https://npm.pkg.github.com"
# yarn config set npmScopes.myorg.npmAuthToken "$GITHUB_PACKAGES_TOKEN"
配置 pip 和 uv,使其从你的私有 PyPI registry (例如 Nexus、Artifactory) 解析软件包。
PYPI_REGISTRY_URL — 你的 PyPI 索引完整 URL,如有需要请包含凭据 (例如 https://user:token@nexus.example.com/repository/pypi-proxy/simple)
maintenance:
- name: Configure pip/uv for private registry
run: |
mkdir -p ~/.config/pip
cat > ~/.config/pip/pip.conf << EOF
[global]
index-url = $PYPI_REGISTRY_URL
EOF
echo "export UV_INDEX_URL=$PYPI_REGISTRY_URL" \
| sudo tee /etc/profile.d/uv-registry.sh > /dev/null
常见的 PyPI registry 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
配置 Poetry,使其从私有 PyPI registry 解析软件包。
POETRY_REGISTRY_URL — 你的 PyPI 兼容 registry 的完整 URL - REGISTRY_USER — registry 用户名 - REGISTRY_PASS — registry 密码或 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 "$POETRY_REGISTRY_URL"
poetry config http-basic.private "$REGISTRY_USER" "$REGISTRY_PASS"
安装 JDK,并将 Maven 配置为通过你的私有 registry (例如 Artifactory、Nexus) 镜像所有依赖解析。JDK 17 已在 Devin 的基础镜像中预装。如果默认的 OpenJDK 17 足够使用,请跳过安装步骤。你只需安装 Maven 并配置 registry。
MAVEN_REGISTRY_URL — 你的 Maven registry URL (例如 https://artifactory.example.com/artifactory/maven-virtual) - REGISTRY_USER — registry 用户名 - REGISTRY_PASS — registry 密码或
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
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>
安装 JDK,并配置 Gradle 以通过你的私有仓库解析所有依赖。Devin 的基础镜像已预装 JDK 17。如果默认版本已足够,请跳过 JDK 安装步骤。
- GRADLE_REGISTRY_URL — 你的 Gradle/Maven 仓库 URL - REGISTRY_USER — 仓库用户名 - REGISTRY_PASS — 仓库密码或 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
安装 Go,并将其配置为通过私有模块代理 (例如 Athens、Artifactory 或 GOPROXY 端点) 解析模块。
GO_PROXY_URL — 你的 Go 模块代理 URL (例如 https://athens.corp.internal) - GIT_TOKEN — 用于托管 Go 模块的私有 Git repo 的 Personal Access Token
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/"
常见的 Go 代理 URL 格式:
- Artifactory:
https://artifactory.example.com/artifactory/go-virtual
- Nexus:
https://nexus.example.com/repository/go-proxy
- Athens:
https://athens.corp.internal
配置 NuGet,以从私有源解析软件包。
- NUGET_SOURCE_URL — 你的 NuGet 源 URL - NUGET_API_KEY — 该源的 API key 或 PAT
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 \
--username any \
--password "$NUGET_API_KEY" \
--store-password-in-clear-text 2>/dev/null || \
dotnet nuget update source private \
--source "$NUGET_SOURCE_URL" \
--username any \
--password "$NUGET_API_KEY" \
--store-password-in-clear-text
配置 Docker 从私有容器注册表拉取镜像。
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 令牌
initialize:
- name: Create Docker config directory
run: sudo mkdir -p /etc/docker
maintenance:
- name: Configure Docker for private registry
run: |
# 配置注册表镜像(可选 — 通过你的注册表转发 Docker Hub 拉取请求)
cat << EOF | sudo tee /etc/docker/daemon.json > /dev/null
{
"registry-mirrors": ["$DOCKER_MIRROR_URL"]
}
EOF
sudo systemctl restart docker || true
# 登录私有容器注册表
echo "$DOCKER_REGISTRY_PASS" | docker login "$DOCKER_REGISTRY_URL" \
--username "$DOCKER_REGISTRY_USER" \
--password-stdin
常见容器注册表 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
配置 Cargo,以从私有 registry 解析 crates。Rust (通过 rustup) 和 Cargo 已预装在 Devin 的基础镜像中。如果默认的 stable 工具链已足够,请跳过安装步骤。你只需要配置 registry。
CARGO_REGISTRY_INDEX — 私有 registry index 的 URL (e.g., sparse+https://cargo.corp.internal/api/v1/crates/) - CARGO_REGISTRY_TOKEN — 私有 registry 的身份验证令牌
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
如果你只想添加私有注册表,而不替换 crates.io,请删除 [source.crates-io] 和 [source.private] 配置段,并使用 cargo install --registry private,或在 Cargo.toml 中使用 [dependencies] my-crate = { version = "1.0", registry = "private" }。
安装 Ruby 并配置 Bundler,以便从私有 gem 服务器解析 gem。
GEM_SERVER_URL — 你的私有 gem 服务器的 URL (例如:https://artifactory.example.com/artifactory/api/gems/gems-virtual) - REGISTRY_USER — Registry 用户名 - REGISTRY_PASS — Registry
密码或 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"
常见的 gem server 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>
安装 PHP 并配置 Composer,以便从私有 Packagist 或 Satis 注册表解析软件包。
COMPOSER_REGISTRY_URL — 你的私有 Composer 注册表的 URL (例如:https://repo.packagist.com/<org>)
REGISTRY_USER — 注册表用户名
REGISTRY_PASS — 注册表密码或 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
# 安装 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"
# 向镜像仓库进行身份验证
composer config --global http-basic.$(echo "$COMPOSER_REGISTRY_URL" \
| sed 's|https\?://||;s|/.*||') "$REGISTRY_USER" "$REGISTRY_PASS"
常见的 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
AWS CodeArtifact 令牌会在 12 小时后过期。请使用 maintenance 在每次会话开始时刷新令牌。此示例会将 npm、pip 和 Maven 配置为使用 CodeArtifact。awscli 已预装在 Devin 的基础镜像中。你只需要刷新令牌并配置 registry。
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 — 各生态对应的仓库名称
maintenance:
- name: Refresh CodeArtifact auth token
run: |
# 获取新令牌(有效期 12 小时)
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"
# 配置 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"
# 配置 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
# 配置 Maven(可选)
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
适用于所有组织和代码仓库的机器级基础架构。可在 Settings > Devin’s base environment (企业范围) 或 Settings > Environment configuration > Org-wide setup (组织范围) 中进行设置。
你的组织为内部服务使用私有证书颁发机构 (CA) 。Devin 需要根证书,才能通过 HTTPS 访问内部制品库和工具。
- CORP_ROOT_CA_B64 — 来自你的企业 CA 的 Base64 编码 PEM 证书。可使用以下命令生成: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
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
如果你的组织使用多个 CA 证书 (例如,不同的内部服务分别使用不同的 CA) 。
- CORP_ROOT_CA_B64 — Base64 编码的主 CA 证书 - CORP_INTERMEDIATE_CA_B64 — Base64 编码的中间 CA 证书
initialize:
- name: Install corporate CA certificates
run: |
echo "$CORP_ROOT_CA_B64" | base64 -d \
| sudo tee /usr/local/share/ca-certificates/corp-root-ca.crt > /dev/null
echo "$CORP_INTERMEDIATE_CA_B64" | base64 -d \
| sudo tee /usr/local/share/ca-certificates/corp-intermediate-ca.crt > /dev/null
sudo update-ca-certificates
# 为需要单个 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
使所有网络流量都通过企业代理转发。
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)
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
maintenance:
- name: Configure git proxy
run: |
git config --global http.proxy "$CORP_HTTP_PROXY"
git config --global https.proxy "$CORP_HTTPS_PROXY"
# 配置 npm 代理
npm config set proxy "$CORP_HTTP_PROXY"
npm config set https-proxy "$CORP_HTTPS_PROXY"
如果你的企业代理需要通过用户名/密码进行身份验证。
PROXY_USER — 代理用户名 - PROXY_PASS — 代理密码 - PROXY_HOST — 代理主机名和端口 (例如 proxy.corp.example.com:8080) - CORP_NO_PROXY — 不经代理的主机
initialize:
- name: Configure authenticated proxy
run: |
PROXY_URL="http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}"
cat << PROXY | sudo tee /etc/profile.d/proxy.sh > /dev/null
export http_proxy="$PROXY_URL"
export https_proxy="$PROXY_URL"
export no_proxy="$CORP_NO_PROXY"
export HTTP_PROXY="$PROXY_URL"
export HTTPS_PROXY="$PROXY_URL"
export NO_PROXY="$CORP_NO_PROXY"
PROXY
source /etc/profile.d/proxy.sh
maintenance:
- name: Configure git for authenticated proxy
run: |
PROXY_URL="http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}"
git config --global http.proxy "$PROXY_URL"
git config --global https.proxy "$PROXY_URL"
适用于同时需要 corporate CA 和代理的环境的组合配置。这在 Enterprise 环境中很常见:内部服务使用私有证书,且所有流量都必须通过代理转发。
CORP_ROOT_CA_B64 — Base64 编码的 corporate CA certificate - CORP_HTTP_PROXY, CORP_HTTPS_PROXY — 代理 URL - CORP_NO_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"
你的私有仓库、Git 服务器或其他内部服务只能通过 VPN 访问。此模块必须在其他需要通过网络访问内部资源的模块之前运行。
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
OpenVPN:initialize:
- name: Install and configure OpenVPN
run: |
sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openvpn
# 写入 VPN 配置
sudo mkdir -p /etc/openvpn/client
echo "$VPN_CONFIG_B64" | base64 -d \
| sudo tee /etc/openvpn/client/corp.conf > /dev/null
# 如果 VPN 需要用户名/密码认证
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
# 启动 VPN 隧道
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
WireGuard:initialize:
- name: Install and configure WireGuard
run: |
sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq wireguard-tools
# 写入 WireGuard 配置
echo "$WG_CONFIG_B64" | base64 -d \
| sudo tee /etc/wireguard/wg0.conf > /dev/null
sudo chmod 600 /etc/wireguard/wg0.conf
# 启动隧道
sudo systemctl enable --now wg-quick@wg0
你的内部服务使用公共 DNS 无法解析的私有 DNS 名称。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
你的组织要求所有 Git 提交都必须签名,并且你希望 GitHub 将 Devin 的提交标记为 Verified。
GPG_PRIVATE_KEY_B64 — Base64 编码的 GPG 私钥。生成命令:gpg --export-secret-keys <key-id> | base64 -w0
GIT_USER_NAME — Git 作者名称 (例如:Devin AI)
GIT_USER_EMAIL — Git 作者邮箱。必须与 GPG 密钥上的某个 UID 匹配,否则 GitHub 不会验证该签名。
initialize:
- name: Prepare GPG and git signing config
run: |
# 允许 GPG 在没有 TTY 的情况下运行
echo 'export GPG_TTY=$(tty)' | sudo tee -a /etc/profile.d/gpg.sh > /dev/null
maintenance:
- name: Import GPG key and configure git signing
run: |
echo "$GPG_PRIVATE_KEY_B64" | base64 -d | gpg --batch --import 2>/dev/null
KEY_ID=$(gpg --list-secret-keys --keyid-format long 2>/dev/null \
| grep sec | head -1 | awk '{print $2}' | cut -d'/' -f2)
git config --global user.signingkey "$KEY_ID"
git config --global commit.gpgsign true
git config --global tag.gpgsign true
git config --global gpg.program gpg
配置 Devin 的 Git 身份和 SSH 密钥,以访问私有 Git 服务器。
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 条目。生成命令:ssh-keyscan git.corp.internal | base64 -w0
SSH_CONFIG_B64 (可选) — Base64 编码的 SSH 配置文件
initialize:
- name: Configure git identity
run: |
git config --global user.name "$GIT_USER_NAME"
git config --global user.email "$GIT_USER_EMAIL"
# 准备 SSH 目录
mkdir -p ~/.ssh && chmod 700 ~/.ssh
maintenance:
- name: Install SSH keys
run: |
# 安装 SSH 私钥(放在 maintenance 中,这样每个 session 都会重新加载)
echo "$SSH_PRIVATE_KEY_B64" | base64 -d > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
# 为你的 Git 服务器添加 known hosts
echo "$SSH_KNOWN_HOSTS_B64" | base64 -d >> ~/.ssh/known_hosts
# 可选:安装自定义 SSH 配置
if [ -n "${SSH_CONFIG_B64:-}" ]; then
echo "$SSH_CONFIG_B64" | base64 -d > ~/.ssh/config
chmod 600 ~/.ssh/config
fi
使用 ssh-keyscan git.corp.internal | base64 -w0 为你的 Git 服务器生成 known hosts 条目。
安装默认 Devin 镜像中不包含的系统级软件包 (例如,用于图像处理或 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
设置在每个会话中都可用的持久环境变量。推荐的做法是将 KEY=VALUE 逐行写入 $ENVRC 文件。写入 $ENVRC 的变量会自动导出到后续所有步骤以及 Devin 会话中 (类似于 GitHub Actions 的 $GITHUB_ENV) 。initialize:
- name: 设置自定义环境变量
run: |
echo "CORPORATE_ENV=production" >> $ENVRC
echo "DEFAULT_REGION=us-east-1" >> $ENVRC
echo "MAX_RETRIES=3" >> $ENVRC
你也可以将环境变量写入 /etc/profile.d/ 脚本,使其在整个系统范围内生效:cat << 'ENVVARS' | sudo tee /etc/profile.d/custom-env.sh > /dev/null
export CORPORATE_ENV=production
export DEFAULT_REGION=us-east-1
ENVVARS
这两种方式都可以。$ENVRC 更简单,也是大多数情况下推荐的做法。
Java、Gradle 和 Node.js 构建经常会达到默认的 1024 个打开文件数限制。请调高该限制,以避免构建失败。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
在隔离或受限环境中,将默认的 Ubuntu APT 软件源替换为内部镜像源。
- APT_MIRROR_URL — 你的内部 APT 镜像源的 URL (例如:https://artifactory.example.com/artifactory/ubuntu-remote)
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
常见的 APT 镜像 URL 格式:
- Artifactory:
https://artifactory.example.com/artifactory/ubuntu-remote
- Nexus:
https://nexus.example.com/repository/ubuntu-proxy
Devin 的基础环境中已包含 direnv。使用 initialize 创建 .envrc 文件后,Direnv 会自动加载它们。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 .
direnv 已预先集成到 Devin 的 shell 中,因此 .envrc 变量会自动加载。无需手动执行 source。
对于敏感环境变量 (API key、令牌、数据库密码) ,请使用 repo secrets,而不是 .envrc 文件。repo secrets 会被安全存储,并在会话开始时注入。它们绝不会出现在你的 blueprint 或快照中。
使用 nvm (已预装) 通过 .nvmrc 为每个仓库切换 Node.js 版本。initialize: |
nvm install 18
nvm install 20
nvm install 22
maintenance: |
nvm use
nvm use 会从仓库根目录读取 .nvmrc。请确保你的仓库中包含该文件 (例如内容为 20) 。
在会话期间,Devin 会提供一个 Chrome 浏览器,其 CDP 端点为 localhost:29229。使用 Playwright 脚本可自动完成基于浏览器的登录。该浏览器仅在会话期间可用,不适用于快照构建。请在 initialize 中安装 Playwright,并将登录脚本保存在你的代码仓库中。
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) :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")
将登录凭据以 secrets 的形式存储,不要写入源代码。对于需要长期保持的身份验证,请将登录脚本提交到 .agents/skills/,以便 Devin 自动重新验证身份。
在 initialize 中安装系统软件包、自定义二进制文件,并配置 PATH。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
Devin 支持在蓝图中直接运行基于 Node.js 的 GitHub Actions。这对于通过 CI 所使用的同一套 actions 安装特定版本的工具非常有用。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
setup-node 和 setup-python 这类 action 会修改 PATH 和环境变量。某个 action 安装的二进制文件在后续所有步骤以及 maintenance 中都可用。仅
支持基于 Node.js 的 GitHub Actions。不支持复合型 action 和基于 Docker 的 action。
你无需依赖 GitHub Actions 来完成基础工具设置。直接使用 shell 命令 (nvm install 20、curl ... | sh、apt-get install) 同样有效,而且通常更简单。只有在你希望与 CI 配置完全一致,或者需要 setup-java 这类可处理多个发行版的 action 所带来的便利时,GitHub Actions 才更有用。
这些示例展示了企业级和组织级配置如何组合使用。实际使用时,通常会按不同作用域拆分。这里将它们集中展示,供参考。
一个完整的企业环境示例:企业 CA 证书、代理、Java (Maven)、Python (pip/uv)、Node.js (npm) 和 Docker,全部指向同一个 Artifactory 实例。
网络与信任 (账户级) :
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)
这通常会拆分为三个作用域:
- 账户级 (
initialize): 证书与代理
- 组织级 (
initialize): 语言运行时安装
- 全组织范围 (
maintenance): 注册表凭据 (每次会话都会刷新)
以下为合并后的完整参考示例: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
# ── Org-wide:语言运行时 ──────────────────────────────────────────
- 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:
# ── 账户级:git 代理(每次会话刷新)───────────────────
- name: Configure git proxy
run: |
git config --global http.proxy "$CORP_HTTP_PROXY"
git config --global https.proxy "$CORP_HTTPS_PROXY"
# ── Org-wide:注册表凭据(每次会话刷新)──────────────────
- 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
在此示例中,所有仓库都指向同一个 Artifactory 实例,但 URL 路径不同。每种软件包生态系统都有各自的端点格式。即使是同一个仓库,Maven、PyPI、npm 和 Docker 的 URL 也各不相同。
当不同语言分别使用不同的私有仓库时 (例如,Maven 使用 Nexus,npm 使用 GitHub Packages,Python 使用 Artifactory) 。
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 令牌 - GIT_TOKEN — 用于 Go 私有模块的个人访问令牌
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(作用域限定)
- 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 → 通过 git 使用私有模块
- name: Configure Go private modules
run: |
git config --global url."https://$GIT_TOKEN@github.com/myorg/".insteadOf "https://github.com/myorg/"
在完全气隙环境中,Devin 无法访问任何公共 URL。所有工具、运行时和软件包都必须来自内部镜像源。
证书:
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
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: |
# 从内部制品库下载 JDK 压缩包
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
在气隙环境中,Devin 所需的所有工具 (语言运行时、CLI 工具等) 都必须能从你的内部镜像源获取。公共软件仓库和下载站点均无法访问。
一个综合性的企业级配置示例,集成了 VPN 连接、证书、代理及多语言支持。以下是推荐的操作顺序。
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 身份验证令牌
initialize:
# 1. VPN — 必须首先执行,以确保内部资源可访问
- 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 — 解析内部主机名
- 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: |
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. 代理 — 通过企业代理路由流量
- 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 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
initialize 步骤的顺序很重要。 必须先配置 VPN (这样才能访问内部主机) ,然后配置 DNS (这样名称才能正确解析) ,再配置证书 (这样 HTTPS 才能正常工作) ,接着配置代理 (这样流量才能正确转发) ,最后配置语言运行时环境 (它们可能会从内部镜像下载) 。
- 先在会话中测试命令。 在将命令添加到蓝图之前,先在 Devin 会话中手动运行一遍。这样比等待完整构建周期更快。
- 一次性安装的工具用
initialize,依赖项用 maintenance。 任何安装需要几分钟的内容 (编译器、大型二进制文件、全局工具) 都应放在 initialize 中。较快的依赖命令 (npm install、uv sync) 则应放在 maintenance 中。
- 让
maintenance 命令保持快速。 尽量控制在 2 分钟以内。这些命令会在每次会话开始时运行。
- 环境变量请使用
$ENVRC。 不要写入 .bashrc 或 .profile。$ENVRC 是在不同步骤和会话之间设置变量的受支持方式。
- 给步骤命名。 使用带有
name 字段的展开形式后,构建日志中的失败会更容易定位。
- monorepo 请使用 subshell。
(cd packages/foo && npm install) 会在 subshell 中运行,因此后续步骤不会受目录变更影响。
- 使用
npm install,不要使用 npm ci。 npm ci 会在每次会话中删除 node_modules 并从头重新安装,这对 maintenance 来说太慢。
- 敏感信息请使用 仓库 secrets。 请在 Settings > Secrets 中按 仓库 作用域配置,而不要将其硬编码到蓝图中。
有关语法细节,请参阅 蓝图参考。有关构建失败的故障排除,请参阅 声明式配置 > 故障排除。