Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# package.json sets "packageManager": "yarn@4.18.0", which the runner's
# bundled Yarn 1 refuses to run. Corepack must be enabled before
# setup-node so its yarn cache detection sees Yarn 4, not Yarn 1.
- name: Enable Corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 22
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile
run: yarn install --immutable
- name: Build website
run: yarn build

Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# package.json sets "packageManager": "yarn@4.18.0", which the runner's
# bundled Yarn 1 refuses to run. Corepack must be enabled before
# setup-node so its yarn cache detection sees Yarn 4, not Yarn 1.
- name: Enable Corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 22
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile
run: yarn install --immutable
- name: Test build website
run: yarn build
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# Dependencies
/node_modules

# Yarn Berry. install-state.gz is a local install cache that is rewritten on
# every `yarn install`, so committing it churns ~1.8MB of binary per install.
# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
.pnp.*

# Production
/build

Expand Down
8 changes: 8 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
approvedGitRepositories:
- "**"

enableScripts: true

nodeLinker: node-modules

npmMinimalAgeGate: 0
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Website

This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.

### Installation

Expand All @@ -24,6 +24,43 @@ $ yarn build

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### The install script

`static/install` is the protoconf installer that the docs point users at:

```
curl -s https://protoconf.dev/install | sh
curl -s https://protoconf.dev/install | sh -s -- protoconf-terraform
```

It installs one of the packages listed in its `select_package` function —
today `protoconf` and `protoconf-terraform`, named as the one positional
argument and defaulting to `protoconf`. Adding another means adding a case
there with the repository, the platforms that repository builds, and a docs
URL; nothing else in the script is package-specific.

Docusaurus copies `static/` verbatim into `build/`, so the file is served at
`/install` with no build step of its own. Two things it depends on:

- **The apex domain has to serve the site directly.** The one-liner above uses
`curl -s` without `-L`, so a redirect from `protoconf.dev` to
`www.protoconf.dev` would pipe an empty body into `sh` and silently install
nothing. Attach both hostnames to the same deployment rather than redirecting
one to the other.
- **`static/_headers`** sets `Content-Type: text/plain` for `/install` on
Cloudflare, so the URL is readable in a browser instead of downloading.

The script takes the release archives published by goreleaser, so the platform
list for each package has to stay in step with the build matrix in that
repository's `.goreleaser.yaml` — they are not the same today: protoconf
publishes a `linux/386` build and protoconf-terraform does not. Test a change
to it end to end, against every package, before merging:

```
sh static/install --dir /tmp/protoconf-install-test
sh static/install protoconf-terraform --dir /tmp/protoconf-install-test
```

### Deployment

Using SSH:
Expand Down
2 changes: 2 additions & 0 deletions blog/2023-05-16-new-site.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Hello to all our amazing users,

We are excited to announce the launch of our new documentation site! We've been hard at work behind the scenes to make it easier for you to find the information you need.

{/* truncate */}

The new site is more than just a fresh coat of paint. It's a fundamental rethinking of how we present information about our product. Our goal is to provide you with clear, concise, and complete information about how to use our services.

Here are some of the new features and improvements we've made:
Expand Down
118 changes: 118 additions & 0 deletions blog/2026-09-03-protoconf-0-2-0.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
slug: protoconf-0-2-0
title: Protoconf v0.2.0
authors: [smintz]
tags: [protoconf, release]
---

Protoconf v0.2.0 is out — the first feature release since v0.1.7. It brings
remote proto modules, staged rollouts, a Kubernetes ConfigMaps backend, one-shot
config reads over gRPC and plain HTTP, opt-in OpenTelemetry, a formatter, and a
single consistent configuration story across every command.

{/* truncate */}

## Remote modules

Configuration repositories can now depend on protos and Starlark that live
somewhere else. Declare the dependency in a `CONFIGSPACE` file, pin it to a tag,
branch, commit or checksum, and let `protoconf mod tidy` resolve it into
`protoconf.lock` and a local cache:

```python title=CONFIGSPACE
platform_protos = remote_repo(
url = "github.com/acme/platform-protos",
tag = "v1.4.0",
)
```

```python title=./src/myproject/server_config.pconf
load("@platform_protos//platform/v1/service.proto", "Service")
```

The lock file is what makes a compile reproducible — commit it next to your
configs. [Remote Modules →](/docs/0.2.0/advanced-usage/modules)

## Staged rollouts

A configuration change is a deploy, and v0.2.0 lets you treat it like one. Wrap
a config in a `ConfigRollout` and it reaches a canary channel first, then a
percentage of your fleet, with a cooldown between each stage:

```python
def main():
return ConfigRollout(
value = ServerConfiguration(max_connections = 2000),
default_cooldown_time = Duration(seconds = 300),
stages = [
RolloutStage(channel = "canary"),
RolloutStage(percentile = 10),
RolloutStage(percentile = 50),
],
)
```

Agents started with `-enable-rollout` pick the first stage they match, hashing
their own identity so the same host lands in the same bucket every time.
Interrupting `protoconf insert` mid-rollout clears the plan and returns every
agent to the stable config. [Staged Rollouts →](/docs/0.2.0/production/rollouts)

## Kubernetes ConfigMaps

`configmaps` is a new key-value backend for both the agent and the inserter, so
a cluster can distribute protoconf configs without running Consul, etcd or
ZooKeeper alongside it:

```bash
protoconf agent -store configmaps -namespace protoconf
```

[Running on Kubernetes →](/docs/0.2.0/production/kubernetes)

## One-shot reads, including over HTTP

Not every consumer is a long-running service. `GetConfig` is the unary
counterpart to `SubscribeForConfig`, for jobs, scripts and init containers. The
agent also transcodes it onto its admin HTTP listener, so anything that can make
an HTTP request can read a config:

```bash
curl http://localhost:4380/v1/config/myproject/server_config
```

[Consuming Configuration Updates →](/docs/0.2.0/consume-config-updates#one-shot-reads)

## Telemetry you opt into

OpenTelemetry export is now off by default and enabled with `-enable-otel`. An
agent that is not asked to export traces installs no-op providers and contacts
nothing. Prometheus metrics stay where they were, on `/metrics`, no flag
required. [Observability →](/docs/0.2.0/production/observability)

## `protoconf fmt`

One canonical layout for `.pconf`, `.mpconf`, `.pinc`, `.proto-validator` and
`.star` files, and a `-l` mode to fail CI when something is unformatted:

```bash
protoconf fmt -w .
```

[Formatting →](/docs/0.2.0/advanced-usage/formatting)

## Two things to check when upgrading

**Configuration precedence.** Every command now resolves configuration as
`flags > environment variables > config file > proto defaults`. `protoconf
agent` used to let a config file override `PROTOCONF_AGENT_*` environment
variables; it no longer does. With repeated `-config-file` flags, the later file
now wins.

**Telemetry is off by default.** An agent that used to reach your collector
automatically needs `-enable-otel` now.

The full list is in
[What's New in v0.2.0](/docs/0.2.0/whats-new-0.2.0), and the complete changelog
is on the [release page](https://github.com/protoconf/protoconf/releases/tag/v0.2.0).

As always, we're on [Discord](https://discord.protoconf.sh) if you hit anything.
4 changes: 2 additions & 2 deletions docs/advanced-usage/_category_.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"label": "Advanced Usage",
"position": 5,
"position": 6,
"link": {
"type": "generated-index",
"description": "Learn more advanced techniques to use protoconf."
}
}
}
60 changes: 60 additions & 0 deletions docs/advanced-usage/formatting.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
id: formatting
title: Formatting Starlark Sources
sidebar_position: 6
---

# Formatting Starlark Sources

:::info New in v0.2.0
:::

`protoconf fmt` formats protoconf's Starlark sources the way `gofmt` formats
Go — one canonical layout, no configuration, no debate in code review.

It handles every Starlark extension protoconf uses:

- `.pconf` — configuration files
- `.mpconf` — multi-output configuration files
- `.pinc` — shared includes
- `.proto-validator` — validation rules
- `.star` — plain Starlark

## Usage

```bash
# Print the formatted result of any file that is not already formatted,
# without changing anything on disk
protoconf fmt

# Rewrite files in place
protoconf fmt -w .

# Show what would change
protoconf fmt -d .

# List only the files that are not formatted — useful in CI
protoconf fmt -l .
```

With no path arguments, `protoconf fmt` walks the current directory
recursively. You can also pass individual files or directories:

```bash
protoconf fmt -w src/myproject/server_config.pconf src/shared/
```

## In continuous integration

`-l` prints the files whose formatting differs and is the check to run in CI:

```yaml title=.github/workflows/protoconf.yml
- name: Check formatting
run: |
unformatted="$(protoconf fmt -l .)"
if [ -n "$unformatted" ]; then
echo "These files need 'protoconf fmt -w':"
echo "$unformatted"
exit 1
fi
```
Loading
Loading