Skip to content

🏭 Satis 私有仓库构建器

18 分钟,用 Composer SDK 的 Satis 方法初始化配置、加仓库、加 require、构建出可托管的静态私有 Packagist。需要本机有 PHP + Composer。

为什么需要 Satis

公司内部有不能上 Packagist 的私有包,但又想用 Composer 统一管理。Satis 把你指定的私有 Git 仓库打包成一个静态网站(含 packages.json),团队 composer install 时直接从这里拉取。

第 1 步:初始化配置

comp.InitSatis(name, homepage, dir)dir 下生成 satis.json 骨架。也可以用 CreateSatisConfig(configPath, name, homepage) 显式指定配置文件路径。

第 2 步:加仓库与 require

  • AddSatisRepository(configPath, type, url) — 往配置里追加一个仓库(type 通常是 git/vcs)。
  • AddSatisRequire(configPath, packageName, version) — 限定只打包某些包;不限定则用 require-all: true

第 3 步:构建

comp.BuildSatis(configPath, outputDir) 执行 satis build,把所有版本下载、打包进 outputDir,返回构建输出文本。

完整可运行示例

go
package main

import (
	"fmt"
	"log"

	"github.com/scagogogo/composer-skills/pkg/composer"
)

func main() {
	comp, err := composer.New(composer.DefaultOptions())
	if err != nil {
		log.Fatal(err)
	}

	const (
		cfgPath = "/tmp/satis/satis.json"
		outDir  = "/tmp/satis/public"
		home    = "https://composer.internal.mycompany.com"
	)

	// 1️⃣ 初始化配置
	if err := comp.InitSatis("mycompany/satis", home, "/tmp/satis"); err != nil {
		log.Fatalf("init: %v", err)
	}
	fmt.Println("📄 satis.json 已生成")

	// 2️⃣ 添加私有 VCS 仓库
	repos := []struct{ typ, url string }{
		{"git", "https://git.internal.mycompany.com/team/auth.git"},
		{"git", "https://git.internal.mycompany.com/team/billing.git"},
	}
	for _, r := range repos {
		if err := comp.AddSatisRepository(cfgPath, r.typ, r.url); err != nil {
			log.Fatalf("add repo %s: %v", r.url, err)
		}
		fmt.Printf("🔗 已加仓库: %s\n", r.url)
	}

	// 3️⃣ 限定打包范围(可选,不限定则 require-all)
	if err := comp.AddSatisRequire(cfgPath, "mycompany/auth", "*"); err != nil {
		log.Fatalf("add require: %v", err)
	}
	if err := comp.AddSatisRequire(cfgPath, "mycompany/billing", "*"); err != nil {
		log.Fatalf("add require: %v", err)
	}

	// 4️⃣ 构建
	output, err := comp.BuildSatis(cfgPath, outDir)
	if err != nil {
		log.Fatalf("build: %v", err)
	}
	fmt.Println("🏗️  构建输出:")
	fmt.Println(output)
	fmt.Printf("✅ 静态仓库已生成于 %s,包含 packages.json\n", outDir)
}

预期输出

📄 satis.json 已生成
🔗 已加仓库: https://git.internal.mycompany.com/team/auth.git
🔗 已加仓库: https://git.internal.mycompany.com/team/billing.git
🏗️  构建输出:
Building dev-main
Collecting packages...
✅ 静态仓库已生成于 /tmp/satis/public,包含 packages.json

第 4 步:让项目消费这个仓库

构建出的 outDir 用任意静态服务器托管(nginx / Caddy / 对象存储)。在消费端 PHP 项目里加上仓库并安装:

bash
composer config repositories.mycompany composer https://composer.internal.mycompany.com
composer require mycompany/auth:"*"

进阶:定制配置结构

pkg/composer.SatisConfig 是公开结构体,可直接读写后用标准 json.MarshalIndent 落盘,灵活控制 minimum-stabilityarchive(打包离线 zip)、providers(V2 分片)等:

go
cfg := composer.SatisConfig{
	Name:             "mycompany/satis",
	Homepage:         home,
	OutputDir:        "public",
	RequireAll:       false,
	MinimumStability: "stable",
	Archive: map[string]interface{}{
		"directory": "dist",
		"format":    "tar",
	},
}
b, _ := json.MarshalIndent(cfg, "", "  ")
os.WriteFile(cfgPath, b, 0644)

require-all vs require

私有包少时用 AddSatisRequire 精确打包,构建快、产物小;包多且都想暴露时用 require-all: trueInitSatis 默认即如此)。

Satis 需要单独安装

Satis 不是 Composer 自带的命令,需先在全局装一次:composer global require composer/satis。本机若未装,BuildSatis 会报命令不存在。

下一步

基于 MIT 许可证发布