release-automation.md
1 # Generic Release Automation 2 3 This repository uses tag-driven publish workflows. The script below standardizes: 4 5 - canonical tag creation for each release target 6 - release note generation from previous release to current commit 7 - GitHub Release create/update 8 9 Script path: 10 11 - `scripts/release/create-release.sh` 12 13 ## Supported Targets 14 15 - `js/sandbox` 16 - `js/code-interpreter` 17 - `python/sandbox` 18 - `python/code-interpreter` 19 - `python/mcp/sandbox` 20 - `java/sandbox` 21 - `java/code-interpreter` 22 - `csharp/sandbox` 23 - `csharp/code-interpreter` 24 - `cli` 25 - `server` 26 - `docker/execd` 27 - `docker/code-interpreter` 28 - `docker/ingress` 29 - `docker/egress` 30 - `k8s/controller` 31 - `k8s/task-executor` 32 - `helm/opensandbox` 33 - `helm` (alias of `helm/opensandbox`) 34 35 ## Tag Rules 36 37 The script aligns with existing workflow triggers: 38 39 - v-prefixed tags: 40 - `<target>/v<version>` for SDK/CLI/Server targets 41 - examples: `js/sandbox/v1.0.5`, `server/v0.2.0` 42 - plain suffix tags: 43 - `<target>/<version>` for docker/k8s/helm targets 44 - examples: `docker/execd/v0.3.0`, `helm/opensandbox/0.1.0` 45 46 ## Release Notes Format 47 48 Generated notes follow `docs/RELEASE_NOTE_TEMPLATE.md` sections: 49 50 - `## What's New` 51 - `### ✨ Features` 52 - `### 🐛 Bug Fixes` 53 - `### ⚠️ Breaking Changes` 54 - `### 📦 Misc` 55 - `## 👥 Contributors` 56 57 Commit categorization: 58 59 - `feat:` -> Features 60 - `fix:` -> Bug Fixes 61 - `BREAKING CHANGE` or `type!:` -> Breaking Changes 62 - everything else -> Misc 63 64 ## Usage 65 66 ```bash 67 scripts/release/create-release.sh --target <target> --version <version> [options] 68 ``` 69 70 Required: 71 72 - `--target` 73 - `--version` 74 75 Options: 76 77 - `--from-tag <tag>`: explicit previous release boundary 78 - `--path <path>`: append custom path filter (repeatable) 79 - `--no-path-filter`: disable default target path scope and use whole range 80 - `--initial-release`: allow no previous tag; use full history 81 - `--dry-run`: render computed tag/range/notes without side effects 82 - `--push`: push created tag to origin 83 84 ## Path Filtering Strategy 85 86 By default, each target only includes commits from target-related paths to reduce noise. 87 88 Examples: 89 90 - `js/sandbox` -> `sdks/sandbox/javascript` + `specs/sandbox-lifecycle.yml` 91 - `server` -> `server` + `specs/sandbox-lifecycle.yml` 92 - `docker/egress` -> `components/egress` 93 - `helm/opensandbox` -> `kubernetes/charts/opensandbox` 94 95 Override behavior: 96 97 - Add extra scope with `--path`: 98 - `--path docs/` or `--path specs/execd-api.yaml` 99 - Disable default scope with `--no-path-filter`: 100 - falls back to the entire commit range (`from..HEAD`) 101 102 ## Common Examples 103 104 Dry-run JavaScript SDK release: 105 106 ```bash 107 scripts/release/create-release.sh --target js/sandbox --version 1.0.5 --dry-run 108 ``` 109 110 Dry-run server release: 111 112 ```bash 113 scripts/release/create-release.sh --target server --version 0.2.0 --dry-run 114 ``` 115 116 Dry-run JavaScript SDK release with additional docs scope: 117 118 ```bash 119 scripts/release/create-release.sh --target js/sandbox --version 1.0.5 --dry-run --path docs/ 120 ``` 121 122 Dry-run JavaScript SDK release without path filtering (full range): 123 124 ```bash 125 scripts/release/create-release.sh --target js/sandbox --version 1.0.5 --dry-run --no-path-filter 126 ``` 127 128 Server release with tag push: 129 130 ```bash 131 scripts/release/create-release.sh --target server --version 0.2.0 --push 132 ``` 133 134 Component image release: 135 136 ```bash 137 scripts/release/create-release.sh --target docker/execd --version v0.3.0 --push 138 ``` 139 140 Helm chart release: 141 142 ```bash 143 scripts/release/create-release.sh --target helm/opensandbox --version 0.1.0 --push 144 ``` 145 146 ## Dry-Run Output Example 147 148 Example output format for `--dry-run`: 149 150 ```text 151 [release] Target: js/sandbox 152 [release] Workflow: .github/workflows/publish-js-sdks.yml 153 [release] New tag: js/sandbox/v1.0.5 154 [release] Previous tag: js/sandbox/v0.1.4 155 [release] Path filters: sdks/sandbox/javascript specs/sandbox-lifecycle.yml 156 [release] Dry run enabled. No tag/release side effects will be performed. 157 [release] Computed range: js/sandbox/v0.1.4..HEAD 158 159 [release] Generated release notes preview: 160 ------------------------------------------------------------ 161 # JavaScript Sandbox SDK v1.0.5 162 ## What's New 163 Changes included since `js/sandbox/v0.1.4`. 164 Scoped paths: `sdks/sandbox/javascript specs/sandbox-lifecycle.yml`. 165 166 ### ✨ Features 167 - feat(sdks/js): support run_in_session 168 169 ### 🐛 Bug Fixes 170 - fix(lifecycle): harden sdk compatibility and e2e stability 171 172 ### ⚠️ Breaking Changes 173 - None 174 175 ### 📦 Misc 176 - chore(sdks): rebuild source code 177 ------------------------------------------------------------ 178 ``` 179 180 If `--dry-run` is enabled, the script never creates/pushes tags and never creates/updates GitHub Releases. 181 182 ## Safety Defaults 183 184 - The script creates/updates GitHub Release only when not in `--dry-run`. 185 - Tag push is opt-in (`--push`), preventing accidental workflow trigger. 186 - If previous tag cannot be found, script fails unless `--from-tag` or `--initial-release` is provided. 187 188 ## GitHub Actions Entry 189 190 You can trigger the same flow in GitHub Actions from: 191 192 - `.github/workflows/release-generic.yml` 193 194 Inputs exposed in the workflow dispatch form: 195 196 - `target` 197 - `version` 198 - `from_tag` (optional) 199 - `initial_release` (boolean) 200 - `push_tag` (boolean) 201 - `dry_run` (boolean, default `true`) 202 203 Dry-run in GitHub Actions: 204 205 - set `dry_run=true` 206 - set `push_tag=false` 207 - check logs for: 208 - computed tag (`New tag`) 209 - range (`Computed range`) 210 - preview body (`Generated release notes preview`) 211 212 Recommended first run in UI: 213 214 - set `dry_run=true` 215 - keep `push_tag=false` 216 - verify the generated release notes preview in logs 217 - rerun with `dry_run=false` and `push_tag=true` when confirmed