Skip to content

Commit cdd3ae6

Browse files
authored
Merge pull request #53 from olblak/policies/index
Publish Policy index
2 parents 42f7601 + 88e4ca9 commit cdd3ae6

File tree

7 files changed

+327
-12
lines changed

7 files changed

+327
-12
lines changed

.ci/scripts/docgen.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import yaml
5+
from dataclasses import dataclass
6+
from typing import List
7+
from urllib.parse import urlparse, urlunparse
8+
9+
@dataclass
10+
class PolicyMetadata:
11+
dir: str
12+
version: str
13+
description: str
14+
path: str
15+
16+
def find_policy_yaml(start_dir=".") -> List[str]:
17+
"""Recursively search for files named 'Policy.yaml'."""
18+
matches = []
19+
for root, _, files in os.walk(start_dir):
20+
if "Policy.yaml" in files:
21+
matches.append(os.path.join(root, "Policy.yaml"))
22+
return matches
23+
24+
def load_policy_metadata(file_path: str) -> PolicyMetadata:
25+
"""Load a Policy.yaml file and unmarshal it into a PolicyMetadata object."""
26+
with open(file_path, "r", encoding="utf-8") as f:
27+
data = yaml.safe_load(f) or {}
28+
29+
dir_name = os.path.dirname(file_path)
30+
return PolicyMetadata(
31+
dir=data.get("dir", dir_name),
32+
version=data.get("version", ""),
33+
description=data.get("description", ""),
34+
path=file_path,
35+
)
36+
37+
def generate_markdown_table(policies: List[PolicyMetadata]) -> str:
38+
"""Generate a Markdown table from a list of PolicyMetadata objects."""
39+
header = "| URL | Version | Description | Link |\n"
40+
separator = "|------------|----------|-----------|---------| \n"
41+
rows = []
42+
for p in policies:
43+
description = p.description.replace("\n", " ").strip()
44+
ghcr_path = f"ghcr.io/updatecli/policies/{os.path.basename(p.path)}"
45+
readme_url = replace_filename_in_url(f"https://github.com/updatecli/policies/tree/main/{p.path}", "README.md")
46+
rows.append(f"| `{ghcr_path or '-'}` | {p.version or '-'} | {description or '-'} | {f"[link]({readme_url})" } |")
47+
return header + separator + "\n".join(rows)
48+
49+
def replace_filename_in_url(url: str, new_filename: str) -> str:
50+
# Parse the URL
51+
parsed = urlparse(url)
52+
53+
# Split the path and replace the last part with the new filename
54+
path_parts = parsed.path.split('/')
55+
path_parts[-1] = new_filename
56+
new_path = '/'.join(path_parts)
57+
58+
# Rebuild the URL with the new path
59+
new_url = urlunparse(parsed._replace(path=new_path))
60+
return new_url
61+
62+
# Example usage
63+
original_url = "https://github.com/updatecli/policies/blob/main/updatecli/policies/file/Policy.yaml"
64+
new_url = replace_filename_in_url(original_url, "Readme.md")
65+
66+
def main():
67+
policies = []
68+
for policy_file in find_policy_yaml("."):
69+
try:
70+
metadata = load_policy_metadata(policy_file)
71+
policies.append(metadata)
72+
except Exception as e:
73+
print(f"⚠️ Error parsing {policy_file}: {e}")
74+
75+
if not policies:
76+
print("No Policy.yaml files found.")
77+
return
78+
79+
markdown = generate_markdown_table(policies)
80+
81+
with open("POLICIES.md", "w", encoding="utf-8") as f:
82+
f.write(markdown)
83+
84+
if __name__ == "__main__":
85+
main()

.github/workflows/updatecli.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: updatecli
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches: [main]
6+
schedule:
7+
# Run every hour
8+
- cron: "0 * * * *"
9+
jobs:
10+
updatecli:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
steps:
15+
- name: "Checkout"
16+
uses: "actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8" # v5.0.0
17+
- name: "Setup updatecli"
18+
uses: "updatecli/updatecli-action@144e241dd804cca91d5a5f362c98b71e7d3ea057" # v2
19+
- uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
20+
id: generate_token
21+
if: github.ref == 'refs/heads/main'
22+
with:
23+
app-id: ${{ secrets.UPDATECLIBOT_APP_ID }}
24+
private-key: ${{ secrets.UPDATECLIBOT_APP_PRIVKEY }}
25+
- name: "Run updatecli"
26+
if: github.ref == 'refs/heads/main'
27+
run: "updatecli compose apply"
28+
env:
29+
UPDATECLI_GITHUB_USERNAME: ${{ secrets.UPDATECLI_BOT_GITHUB_ACTOR }}
30+
UPDATECLI_GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}

README.adoc

Lines changed: 148 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,73 @@
11
= README
22

3+
image:https://www.updatecli.io/images/updatecli.png[alt=Updatecli,float="right",align="center",width=200,height=200]
4+
35
link:https://matrix.to/#/#Updatecli_community:gitter.im[image:https://img.shields.io/matrix/updatecli:matrix.org[]]
46
link:https://github.com/updatecli/policies/blob/main/LICENSE[image:https://img.shields.io/github/license/updatecli/policies[GitHub]]
57
link:https://img.shields.io/github/actions/workflow/status/updatecli/policies/validate.yaml?branch=main[image:https://img.shields.io/github/actions/workflow/status/updatecli/policies/validate.yaml?branch=main[GitHub Workflow Status]]
68

79

8-
This repository contains a list of common Updatecli published on ghcr.io/updatecli/policies/**
10+
These repository contains a list of common Updatecli policies that can be used to automate the update of various software components.
11+
These policies are published on `ghcr.io/updatecli/policies` docker registry and can be used directly by Updatecli users.
12+
Policies are designed to be as generic as possible to fit most use cases and can be customized via values files at runtime.
13+
They follow semantic versioning to ensure compatibility and stability.
14+
15+
== Policies
16+
17+
A list of all available policies can be found link:./POLICIES.md[here].
18+
19+
== Quick Start
20+
21+
Pull and inspect a policy manifest:
22+
23+
[source,shell]
24+
----
25+
updatecli manifest show ghcr.io/updatecli/policies/autodiscovery/golang:latest
26+
----
27+
28+
Run a single policy (dry-run):
29+
30+
[source,shell]
31+
----
32+
updatecli diff ghcr.io/updatecli/policies/autodiscovery/golang:latest
33+
----
34+
35+
Apply a single policy:
36+
37+
[source,shell]
38+
----
39+
updatecli apply --config ghcr.io/updatecli/policies/autodiscovery/golang:latest
40+
----
41+
42+
Compose multiple policies using an updatecli-compose file:
43+
44+
* Create `updatecli-compose.yaml` (example below).
45+
* Run:
46+
[source,shell]
47+
----
48+
updatecli compose apply --config ./updatecli-compose.yaml
49+
----
50+
51+
.updatecli-compose.yaml
52+
----
53+
policies:
54+
- policy: "ghcr.io/updatecli/policies/autodiscovery/golang:latest"
55+
- policy: "ghcr.io/updatecli/policies/autodiscovery/npm:latest"
56+
----
57+
58+
Please be aware that each policies comes with its own set of configuration options so please refer to the policy documentation for more information.
59+
You can replace the policy `ghcr.io/updatecli/policies/autodiscovery/all:latest` by any other policy available in this repository.
60+
61+
== Authentication / Registry
62+
63+
Policies are published on `ghcr.io`. Public pulls usually work, but authenticating reduces rate-limiting:
64+
65+
[source,shell]
66+
----
67+
docker login ghcr.io
68+
----
69+
70+
If you need to pull private policies, provide credentials via your container/runtime or via Updatecli's registry auth options.
971

1072
== HOWTO
1173

@@ -23,24 +85,24 @@ Each policies defines in this repository are automatically published on ghcr.io
2385

2486
We can see the content of the policy by running:
2587

26-
updatecli manifest show ghcr.io/updatecli/policies/<a policy name>:latest
88+
updatecli manifest show --config updatecli.d --values values.yaml
2789

2890
**Use**
2991

30-
They are two ways to execute an Updatecli policy, either running one policy or several policies at once.
92+
There are two ways to execute an Updatecli policy, either running one policy or several policies at once.
3193

3294
One policy can be executed by running:
3395

34-
updatecli apply --config ghcr.io/updatecli/policies/<a policy name>:latest
96+
updatecli apply --config ghcr.io/updatecli/policies/<policy-path>:<version>
3597

3698

3799
IMPORTANT: Any values files specified at runtime will override default values setting from the policy bundle
38100

39-
Assuming we have a file named `update-compose.yaml`, multiple policies can be composed and executed by running:
101+
Assuming we have a file named `updatecli-compose.yaml`, multiple policies can be composed and executed by running:
40102

41-
updatecli compose apply
103+
updatecli compose apply --config ./updatecli-compose.yaml
42104

43-
.update-compose.yaml
105+
.updatecli-compose.yaml
44106
```yaml
45107
policies:
46108
- policy: "ghcr.io/updatecli/policies/autodiscovery/golang:latest"
@@ -51,7 +113,80 @@ More information about Updatecli compose feature can be found link:https://www.u
51113

52114
== CONTRIBUTING
53115

54-
Policies can be added by creating a new folder under `updatecli/policies` directory.
116+
Thank you for your interest in contributing to this project.
117+
Here is a none exclusive list of contribution you can do.
118+
119+
=== Documentation
120+
121+
This project would benefit from clearer policy README files. Please improve each policy's README to explain how to use and configure the policy.
122+
123+
To inspect a policy bundle locally (manifest and default values):
124+
125+
[source,shell]
126+
----
127+
# Show the generated manifest (uses files in the policy bundle directory)
128+
updatecli manifest show --config updatecli.d --values values.yaml
129+
130+
# Show the manifest and render a graph (Mermaid)
131+
updatecli manifest show --config updatecli.d --values values.yaml --graph --graph-flavor mermaid
132+
----
133+
134+
Notes:
135+
* `--config updatecli.d` reads policy manifests shipped inside the policy bundle.
136+
* `--values values.yaml` overrides default policy values for local inspection.
137+
138+
When running policies, prefer pinning by version or digest to ensure reproducible runs:
139+
* By tag: `ghcr.io/updatecli/policies/autodiscovery/golang:1.0.0`
140+
* By digest: `ghcr.io/updatecli/policies/autodiscovery/golang@sha256:<digest>`
141+
142+
Authentication:
143+
* Public pulls usually work, but authenticating with GHCR reduces rate limits:
144+
[source,shell]
145+
----
146+
docker login ghcr.io
147+
----
148+
* For private bundles, provide registry credentials to your runtime or via Updatecli's registry auth options.
149+
150+
Publishing:
151+
* Policies in this repository are published automatically by CI when `Policy.yaml` version is bumped.
152+
* See the `Policy.yaml` template below and ensure you update the `version` field for releases.
153+
154+
Policy inspection and usage summary:
155+
* Inspect: `updatecli manifest show --config updatecli.d --values values.yaml`
156+
* Dry-run: `updatecli diff ghcr.io/updatecli/policies/<path>:<version>`
157+
* Apply: `updatecli apply --config ghcr.io/updatecli/policies/<path>:<version>`
158+
159+
Tip: add a short example `values.yaml` in each policy README to help users test quickly.
160+
161+
=== Updating Policy
162+
163+
Before changing an existing policy, open a GitHub issue to discuss the proposed change. Use the issue to explain:
164+
* Motivation and user impact
165+
* Backwards compatibility implications
166+
* Required changes to `Policy.yaml`, `values.yaml`, or `updatecli.d`
167+
* Testing plan (how the change will be validated)
168+
169+
When preparing a PR:
170+
* Bump `Policy.yaml` version for behavioural changes (semantic versioning).
171+
* Update `CHANGELOG.md` and the policy `README.md` with usage and configuration changes.
172+
* Add or update `values.yaml` examples if defaults change.
173+
* Ensure policy validation CI (lint/manifest tests) passes.
174+
175+
PR checklist:
176+
* [ ] Issue opened describing the change (link in PR)
177+
* [ ] `Policy.yaml` version updated when needed
178+
* [ ] `CHANGELOG.md` updated
179+
* [ ] README and example `values.yaml` updated
180+
* [ ] All CI checks pass (policy validation workflow)
181+
182+
Notes:
183+
* Policies are published automatically by CI when `Policy.yaml.version` is updated.
184+
* For large or breaking changes, discuss a migration plan in the issue and notify maintainers.
185+
* For security-related changes, include an explanation and coordinate disclosure with maintainers.
186+
187+
=== New Policy
188+
189+
A new policy can be added by creating a new folder under the `updatecli/policies` directory.
55190
The subfolder path will be used as the policy name.
56191

57192
For example if we want to create a policy named `autodiscovery/golang`, we need to create a folder named `updatecli/policies/autodiscovery/golang`.
@@ -89,12 +224,13 @@ Any change to the policy code must be reflected by a new version. Policies are a
89224

90225
=== Why a monorepo ?
91226

92-
A monorepo is a repository that contains multiple projects. In our case, we have a single repository that contains multiple Updatecli policies.
227+
A monorepo simplifies policy discovery and publishing while we build tooling and CI. We may split later if needed.
93228

94-
We are still in a very early stage and we are not sure yet if we will keep this repository as a monorepo or if we will split it into multiple repositories.
229+
== Thanks to all the contributors ❤️
95230

96-
But it is easier to handle a monorepo than multiple repositories while we build the tooling and the process to manage Updatecli policies.
231+
link:https://github.com/updatecli/policies/graphs/contributors"[image:https://contrib.rocks/image?repo=updatecli/policies[]]
97232

98233
== LINKS
99234

100-
* link:https://www.updatecli.io/docs/core/compose/[here]
235+
* link:https://www.updatecli.io/docs/core/compose/[Updatecli Compose documentation]
236+
* link:./POLICIES.md[Full Policy list]

updatecli-compose.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
policies:
2+
- name: Local Updatecli policies
3+
config:
4+
- updatecli/updatecli.d
5+
values:
6+
- updatecli/values.d/scm.yaml
7+
8+
- name: Update githubactions
9+
policy: ghcr.io/updatecli/policies/autodiscovery/githubaction:0.2.1@sha256:cfddec11464cc09615135f0f1e069f00ad24d28edc7cc6a4e8224e04c3699008
10+
values:
11+
- updatecli/values.d/scm.yaml
12+
- updatecli/values.d/githubaction.yaml
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Update POLICIES.md
2+
3+
actions:
4+
default:
5+
title: "deps: update POLICIES.md"
6+
kind: github/pullrequest
7+
scmid: default
8+
spec:
9+
automerge: true
10+
labels:
11+
- documentation
12+
13+
scms:
14+
default:
15+
kind: github
16+
spec:
17+
branch: "{{ .scm.branch }}"
18+
email: "{{ .scm.email }}"
19+
owner: "{{ .scm.owner }}"
20+
repository: "{{ .scm.repository }}"
21+
user: "{{ .scm.user }}"
22+
23+
conditions:
24+
python:
25+
name: Check if Python is installed
26+
kind: shell
27+
spec:
28+
command: "python3 --version"
29+
30+
targets:
31+
policies:
32+
name: update POLICIES.md
33+
kind: shell
34+
spec:
35+
command: .ci/scripts/docgen.py
36+
changedif:
37+
kind: file/checksum
38+
spec:
39+
files:
40+
- "POLICIES.md"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
spec:
2+
digest: true
3+
rootdir: '.github'

updatecli/values.d/scm.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
scm:
2+
commitusingapi: true
3+
enabled: true
4+
user: updatecli
5+
email: bot@updatecli.io
6+
owner: updatecli
7+
repository: policies
8+
username: "updatecli-bot"
9+
branch: main

0 commit comments

Comments
 (0)