turbo-editors/turbo-gopublic Fork 0
358e481
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-go.git
git clone ssh://git@rickub.com/turbo-editors/turbo-go.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

🛟 Updated.

k33g committed 2026-09-20T09:39:43+02:00 Browse files
358e481 parent: 0c719ab
modified .github/workflows/release.yml +3 -2
@@ -60,8 +60,9 @@ jobs:
6060 run: go test ./... -count=1
6161
6262 - name: Build the release
63- # release.env is git-ignored, so the tag is passed explicitly and the
64- # script falls back to "Turbo Go <tag>" for the description.
63+ # The tag is passed explicitly — the one just pushed — so release.env, which
64+ # is committed, cannot make the build disagree with it. ABOUT is still read
65+ # from the file for the description, "Turbo Go <tag>" being the fallback.
6566 run: bash ./02-build-releases.sh "${GITHUB_REF_NAME}"
6667
6768 - name: Release notes
@@ -60,8 +60,9 @@ jobs:
60 run: go test ./... -count=160 run: go test ./... -count=1
61 61
62 - name: Build the release62 - name: Build the release
63- # release.env is git-ignored, so the tag is passed explicitly and the63+ # The tag is passed explicitly — the one just pushed — so release.env, which
64- # script falls back to "Turbo Go <tag>" for the description.64+ # is committed, cannot make the build disagree with it. ABOUT is still read
65+ # from the file for the description, "Turbo Go <tag>" being the fallback.
65 run: bash ./02-build-releases.sh "${GITHUB_REF_NAME}"66 run: bash ./02-build-releases.sh "${GITHUB_REF_NAME}"
66 67
67 - name: Release notes68 - name: Release notes
modified .gitignore +4 -0
@@ -1,6 +1,10 @@
11 bin/
22 kits
33 *.env
4+# release.env is the one .env that is committed: it carries the version being
5+# published and its one-line description, which are part of the project's
6+# record. Token files (*.token.env) stay under the rule above.
7+!release.env
48 release
59
610 # A go.work pointing at the checkout beside this one is how you build against an
@@ -1,6 +1,10 @@
1 bin/1 bin/
2 kits2 kits
3 *.env3 *.env
4+# release.env is the one .env that is committed: it carries the version being
5+# published and its one-line description, which are part of the project's
6+# record. Token files (*.token.env) stay under the rule above.
7+!release.env
4 release8 release
5 9
6 # A go.work pointing at the checkout beside this one is how you build against an10 # A go.work pointing at the checkout beside this one is how you build against an
modified .memory/handoffs/2026-09-20-load-config.md +8 -0
@@ -20,3 +20,11 @@
2020
2121 `demo/README.md`, `demo/go.mod`, `demo/index.html`, `demo/index.js`, `demo/main.go` are deleted in the working tree (`git status` shows `D`), and an untracked `demo-golang` binary (6.9 MB) sits at the module root. No test or script here deletes `demo/` (grep of `*.sh`, `Makefile`, `*_test.go`), the reflog shows no git operation, and the folder is kDrive-synced — most likely something done on the host. Not restored by this session; `git checkout -- demo` brings the files back if that was not intended. Note `demo/go.mod` is also what a root `go.work` must list to run `go` inside `demo/`.
2222
23+## Also
24+
25+`release.env` is committed from now on (`!release.env` in `.gitignore`). `01-release.tag.sh` does `git add .`, so the next release commits it by itself.
26+
27+## Update, end of session
28+
29+turbo-core v1.0.3 is published and `go.mod` pins it (done from the host, with a commit, during the session). Step 1 of "Next steps" is done; the two release-script tests are expected green again — see the history entry for the run that confirmed it.
30+
@@ -20,3 +20,11 @@
20 20
21 `demo/README.md`, `demo/go.mod`, `demo/index.html`, `demo/index.js`, `demo/main.go` are deleted in the working tree (`git status` shows `D`), and an untracked `demo-golang` binary (6.9 MB) sits at the module root. No test or script here deletes `demo/` (grep of `*.sh`, `Makefile`, `*_test.go`), the reflog shows no git operation, and the folder is kDrive-synced — most likely something done on the host. Not restored by this session; `git checkout -- demo` brings the files back if that was not intended. Note `demo/go.mod` is also what a root `go.work` must list to run `go` inside `demo/`.21 `demo/README.md`, `demo/go.mod`, `demo/index.html`, `demo/index.js`, `demo/main.go` are deleted in the working tree (`git status` shows `D`), and an untracked `demo-golang` binary (6.9 MB) sits at the module root. No test or script here deletes `demo/` (grep of `*.sh`, `Makefile`, `*_test.go`), the reflog shows no git operation, and the folder is kDrive-synced — most likely something done on the host. Not restored by this session; `git checkout -- demo` brings the files back if that was not intended. Note `demo/go.mod` is also what a root `go.work` must list to run `go` inside `demo/`.
22 22
23+## Also
24+
25+`release.env` is committed from now on (`!release.env` in `.gitignore`). `01-release.tag.sh` does `git add .`, so the next release commits it by itself.
26+
27+## Update, end of session
28+
29+turbo-core v1.0.3 is published and `go.mod` pins it (done from the host, with a commit, during the session). Step 1 of "Next steps" is done; the two release-script tests are expected green again — see the history entry for the run that confirmed it.
30+
modified .memory/history.md +2 -0
@@ -523,4 +523,6 @@
523523 - **Depends on turbo-core v1.0.3**, not yet tagged: `go.mod` still pins v1.0.2, so this builds only under the umbrella `go.work` (`turbo-editors/README.md` explains) until `go get rickub.com/turbo-editors/turbo-core@v1.0.3 && go mod tidy`. Verified with `make check` under that workspace.
524524 - **Not done**: not committed; go.mod not re-pinned; not run against a real terminal.
525525 - **Correction, same session**: under the workspace everything passes **except `TestTheTagScriptTagsAndPushesForReal` and `TestTheTagScriptRefusesATagItAlreadyPublished`** — they copy the module elsewhere and run `make check` there, outside the workspace, where turbo-core v1.0.2 from the proxy has no `configrepo`. They go green the moment `go.mod` is re-pinned to v1.0.3. The package diagram (`docs/diagrams/packages.drawio`, where the module has one) gained a `configrepo` box and a `main → configrepo` arrow, which its own test demanded.
526+- **Later, same session**: `release.env` is now **committed** — `.gitignore` gained `!release.env` under `*.env`, with a comment; `*.token.env` files stay ignored (verified with `git check-ignore` in every repository). The comments that said it was ignored were reworded to match: `02-build-releases.sh`, `.github/workflows/release.yml`, the release how-to (EN+FR), and this summary. Asked by the user so the version and its description travel with the repository.
527+- **End of session**: turbo-core v1.0.3 having been published and `go.mod` re-pinned to it from the host, `GOWORK=off go test ./... -count=1` is entirely green here, the two release-script tests included.
526528
@@ -523,4 +523,6 @@
523 - **Depends on turbo-core v1.0.3**, not yet tagged: `go.mod` still pins v1.0.2, so this builds only under the umbrella `go.work` (`turbo-editors/README.md` explains) until `go get rickub.com/turbo-editors/turbo-core@v1.0.3 && go mod tidy`. Verified with `make check` under that workspace.523 - **Depends on turbo-core v1.0.3**, not yet tagged: `go.mod` still pins v1.0.2, so this builds only under the umbrella `go.work` (`turbo-editors/README.md` explains) until `go get rickub.com/turbo-editors/turbo-core@v1.0.3 && go mod tidy`. Verified with `make check` under that workspace.
524 - **Not done**: not committed; go.mod not re-pinned; not run against a real terminal.524 - **Not done**: not committed; go.mod not re-pinned; not run against a real terminal.
525 - **Correction, same session**: under the workspace everything passes **except `TestTheTagScriptTagsAndPushesForReal` and `TestTheTagScriptRefusesATagItAlreadyPublished`** — they copy the module elsewhere and run `make check` there, outside the workspace, where turbo-core v1.0.2 from the proxy has no `configrepo`. They go green the moment `go.mod` is re-pinned to v1.0.3. The package diagram (`docs/diagrams/packages.drawio`, where the module has one) gained a `configrepo` box and a `main → configrepo` arrow, which its own test demanded.525 - **Correction, same session**: under the workspace everything passes **except `TestTheTagScriptTagsAndPushesForReal` and `TestTheTagScriptRefusesATagItAlreadyPublished`** — they copy the module elsewhere and run `make check` there, outside the workspace, where turbo-core v1.0.2 from the proxy has no `configrepo`. They go green the moment `go.mod` is re-pinned to v1.0.3. The package diagram (`docs/diagrams/packages.drawio`, where the module has one) gained a `configrepo` box and a `main → configrepo` arrow, which its own test demanded.
526+- **Later, same session**: `release.env` is now **committed** — `.gitignore` gained `!release.env` under `*.env`, with a comment; `*.token.env` files stay ignored (verified with `git check-ignore` in every repository). The comments that said it was ignored were reworded to match: `02-build-releases.sh`, `.github/workflows/release.yml`, the release how-to (EN+FR), and this summary. Asked by the user so the version and its description travel with the repository.
527+- **End of session**: turbo-core v1.0.3 having been published and `go.mod` re-pinned to it from the host, `GOWORK=off go test ./... -count=1` is entirely green here, the two release-script tests included.
526 528
modified .memory/summary.md +2 -2
@@ -186,7 +186,7 @@ Reports land in `.quality/`; exit code 0 = pass.
186186
187187 ## Release tooling
188188
189-`01-release.tag.sh` and `02-build-releases.sh` in the repository root, plus `.github/workflows/release.yml`, modelled on turbo-core's. `release.env` carries `TAG` and `ABOUT` and is gitignored (`*.env`); there is no token file any more.
189+`01-release.tag.sh` and `02-build-releases.sh` in the repository root, plus `.github/workflows/release.yml`, modelled on turbo-core's. `release.env` carries `TAG` and `ABOUT` and is **committed** (`!release.env` under `*.env` in `.gitignore`, since 2026-09-20); there is no token file any more.
190190
191191 `01` tags; the tag push starts the workflow. It exports `TURBO_GO_RELEASING=1` before `make check` so the tests that run `01` against a throwaway clone do not recurse; the workflow sets the same variable for its `go test` step. `02-build-releases.sh` cross-compiles for the platforms in its own `PLATFORMS` array and writes `release/${TAG}/` (binaries, `SHA256SUMS`, `README.md`); adding a target is one line and the checksums and README follow. It takes the tag as its first argument (what CI does, having no `release.env`), validates it as `vX.Y.Z[-pre]`, refuses a `replace` in `go.mod`, and starts from an empty `release/${TAG}/`. The workflow attaches `turbo-go-*`, `SHA256SUMS` and `README.md` with `softprops/action-gh-release@v2`, `fail_on_unmatched_files: true`, and writes release notes from the tag's message with the docs linked at that tag. Rickub's release API takes only the job's `GITHUB_TOKEN` (a personal token is refused), and its dispatch API fires every dispatchable workflow of a ref — hence `contents: write`, no `secrets.`, and no `workflow_dispatch`.
192192
@@ -210,5 +210,5 @@ Reports land in `.quality/`; exit code 0 = pass.
210210
211211 ## State as of 2026-09-20
212212
213-- **`-load-config <url>` is wired** (`main.go`: `loadConfig`, `describeLoad`), on top of turbo-core's `configrepo`. It needs **turbo-core v1.0.3**, which is not tagged yet; `go.mod` pins v1.0.2, so the editor builds only under the umbrella `go.work` until re-pinned. A project with a `.turbo-go` already is refused, not overwritten.
213+- **`-load-config <url>` is wired** (`main.go`: `loadConfig`, `describeLoad`), on top of turbo-core's `configrepo`. `go.mod` pins **turbo-core v1.0.3**, which is published (re-pinned from the host on 2026-09-20), so it builds on its own again. A project with a `.turbo-go` already is refused, not overwritten.
214214
@@ -186,7 +186,7 @@ Reports land in `.quality/`; exit code 0 = pass.
186 186
187 ## Release tooling187 ## Release tooling
188 188
189-`01-release.tag.sh` and `02-build-releases.sh` in the repository root, plus `.github/workflows/release.yml`, modelled on turbo-core's. `release.env` carries `TAG` and `ABOUT` and is gitignored (`*.env`); there is no token file any more.189+`01-release.tag.sh` and `02-build-releases.sh` in the repository root, plus `.github/workflows/release.yml`, modelled on turbo-core's. `release.env` carries `TAG` and `ABOUT` and is **committed** (`!release.env` under `*.env` in `.gitignore`, since 2026-09-20); there is no token file any more.
190 190
191 `01` tags; the tag push starts the workflow. It exports `TURBO_GO_RELEASING=1` before `make check` so the tests that run `01` against a throwaway clone do not recurse; the workflow sets the same variable for its `go test` step. `02-build-releases.sh` cross-compiles for the platforms in its own `PLATFORMS` array and writes `release/${TAG}/` (binaries, `SHA256SUMS`, `README.md`); adding a target is one line and the checksums and README follow. It takes the tag as its first argument (what CI does, having no `release.env`), validates it as `vX.Y.Z[-pre]`, refuses a `replace` in `go.mod`, and starts from an empty `release/${TAG}/`. The workflow attaches `turbo-go-*`, `SHA256SUMS` and `README.md` with `softprops/action-gh-release@v2`, `fail_on_unmatched_files: true`, and writes release notes from the tag's message with the docs linked at that tag. Rickub's release API takes only the job's `GITHUB_TOKEN` (a personal token is refused), and its dispatch API fires every dispatchable workflow of a ref — hence `contents: write`, no `secrets.`, and no `workflow_dispatch`.191 `01` tags; the tag push starts the workflow. It exports `TURBO_GO_RELEASING=1` before `make check` so the tests that run `01` against a throwaway clone do not recurse; the workflow sets the same variable for its `go test` step. `02-build-releases.sh` cross-compiles for the platforms in its own `PLATFORMS` array and writes `release/${TAG}/` (binaries, `SHA256SUMS`, `README.md`); adding a target is one line and the checksums and README follow. It takes the tag as its first argument (what CI does, having no `release.env`), validates it as `vX.Y.Z[-pre]`, refuses a `replace` in `go.mod`, and starts from an empty `release/${TAG}/`. The workflow attaches `turbo-go-*`, `SHA256SUMS` and `README.md` with `softprops/action-gh-release@v2`, `fail_on_unmatched_files: true`, and writes release notes from the tag's message with the docs linked at that tag. Rickub's release API takes only the job's `GITHUB_TOKEN` (a personal token is refused), and its dispatch API fires every dispatchable workflow of a ref — hence `contents: write`, no `secrets.`, and no `workflow_dispatch`.
192 192
@@ -210,5 +210,5 @@ Reports land in `.quality/`; exit code 0 = pass.
210 210
211 ## State as of 2026-09-20211 ## State as of 2026-09-20
212 212
213-- **`-load-config <url>` is wired** (`main.go`: `loadConfig`, `describeLoad`), on top of turbo-core's `configrepo`. It needs **turbo-core v1.0.3**, which is not tagged yet; `go.mod` pins v1.0.2, so the editor builds only under the umbrella `go.work` until re-pinned. A project with a `.turbo-go` already is refused, not overwritten.213+- **`-load-config <url>` is wired** (`main.go`: `loadConfig`, `describeLoad`), on top of turbo-core's `configrepo`. `go.mod` pins **turbo-core v1.0.3**, which is published (re-pinned from the host on 2026-09-20), so it builds on its own again. A project with a `.turbo-go` already is refused, not overwritten.
214 214
modified 02-build-releases.sh +5 -4
@@ -23,10 +23,11 @@ COMMENT
2323 set -euo pipefail
2424
2525 # release.env carries TAG ("v1.0.0") and ABOUT (the one-line description). It
26-# is git-ignored (*.env), so a CI job does not have it: there the tag comes
27-# from the command line and ABOUT from the environment, or defaults to the
28-# tag. A tag given on the command line always wins, so a test build never
29-# edits the file.
26+# is committed — the one .env that is — so a CI job has it too and reads ABOUT
27+# from it; there the tag still comes from the command line, the tag that was
28+# pushed, so the file cannot make a build disagree with the tag it is on. With
29+# no ABOUT anywhere it defaults to the tag. A tag given on the command line
30+# always wins, so a test build never edits the file.
3031 if [ -f release.env ]; then
3132 # shellcheck source=/dev/null
3233 source release.env
@@ -23,10 +23,11 @@ COMMENT
23 set -euo pipefail23 set -euo pipefail
24 24
25 # release.env carries TAG ("v1.0.0") and ABOUT (the one-line description). It25 # release.env carries TAG ("v1.0.0") and ABOUT (the one-line description). It
26-# is git-ignored (*.env), so a CI job does not have it: there the tag comes26+# is committed — the one .env that is — so a CI job has it too and reads ABOUT
27-# from the command line and ABOUT from the environment, or defaults to the27+# from it; there the tag still comes from the command line, the tag that was
28-# tag. A tag given on the command line always wins, so a test build never28+# pushed, so the file cannot make a build disagree with the tag it is on. With
29-# edits the file.29+# no ABOUT anywhere it defaults to the tag. A tag given on the command line
30+# always wins, so a test build never edits the file.
30 if [ -f release.env ]; then31 if [ -f release.env ]; then
31 # shellcheck source=/dev/null32 # shellcheck source=/dev/null
32 source release.env33 source release.env
modified docs/en/how-to/make-a-release.md +1 -1
@@ -53,7 +53,7 @@ Theme: Turbo Classic
5353
5454 ## Or use the scripts and let the workflow publish
5555
56-That is the way a release is actually cut. Put the version and its one-line description in `release.env` — it is gitignored, so CI never sees it:
56+That is the way a release is actually cut. Put the version and its one-line description in `release.env` — it is committed with the release, and CI takes the tag from the push rather than from it:
5757
5858 ```sh
5959 TAG="v1.0.0"
@@ -53,7 +53,7 @@ Theme: Turbo Classic
53 53
54 ## Or use the scripts and let the workflow publish54 ## Or use the scripts and let the workflow publish
55 55
56-That is the way a release is actually cut. Put the version and its one-line description in `release.env` — it is gitignored, so CI never sees it:56+That is the way a release is actually cut. Put the version and its one-line description in `release.env` — it is committed with the release, and CI takes the tag from the push rather than from it:
57 57
58 ```sh58 ```sh
59 TAG="v1.0.0"59 TAG="v1.0.0"
modified docs/fr/how-to/make-a-release.md +1 -1
@@ -53,7 +53,7 @@ Theme: Turbo Classic
5353
5454 ## Ou utiliser les scripts et laisser le workflow publier
5555
56-C'est ainsi qu'une release est réellement faite. Mettez la version et sa description d'une ligne dans `release.env` — il est ignoré par git, donc la CI ne le voit jamais :
56+C'est ainsi qu'une release est réellement faite. Mettez la version et sa description d'une ligne dans `release.env` — il est versionné avec la release, et la CI prend le tag du push plutôt que dans ce fichier :
5757
5858 ```sh
5959 TAG="v1.0.0"
@@ -53,7 +53,7 @@ Theme: Turbo Classic
53 53
54 ## Ou utiliser les scripts et laisser le workflow publier54 ## Ou utiliser les scripts et laisser le workflow publier
55 55
56-C'est ainsi qu'une release est réellement faite. Mettez la version et sa description d'une ligne dans `release.env` — il est ignoré par git, donc la CI ne le voit jamais :56+C'est ainsi qu'une release est réellement faite. Mettez la version et sa description d'une ligne dans `release.env` — il est versionné avec la release, et la CI prend le tag du push plutôt que dans ce fichier :
57 57
58 ```sh58 ```sh
59 TAG="v1.0.0"59 TAG="v1.0.0"
added release.env +10 -0
new file mode 100644
@@ -0,0 +1,10 @@
1+# Edited before every release, then:
2+# ./01-release.tag.sh make check, commit, push, tag, push the tag
3+# (pushing the tag starts .github/workflows/release.yml, which builds the
4+# binaries with ./02-build-releases.sh and publishes the release with them —
5+# no personal token is needed, and nothing else has to be run)
6+#
7+# ./02-build-releases.sh v1.0.0 to build the binaries by hand and see what
8+# the CI will publish, without publishing anything
9+TAG="v1.0.3"
10+ABOUT="Turbo Go"
new file mode 100644
@@ -0,0 +1,10 @@
1+# Edited before every release, then:
2+# ./01-release.tag.sh make check, commit, push, tag, push the tag
3+# (pushing the tag starts .github/workflows/release.yml, which builds the
4+# binaries with ./02-build-releases.sh and publishes the release with them —
5+# no personal token is needed, and nothing else has to be run)
6+#
7+# ./02-build-releases.sh v1.0.0 to build the binaries by hand and see what
8+# the CI will publish, without publishing anything
9+TAG="v1.0.3"
10+ABOUT="Turbo Go"
modified release_test.go +4 -3
@@ -469,9 +469,10 @@ func writeFile(t *testing.T, path, contents string) {
469469 }
470470
471471 func TestTheBuildScriptTakesTheTagFromTheCommandLine(t *testing.T) {
472- // release.env is git-ignored, so the workflow has none: it passes the tag
473- // it was started by. A script that only reads the file builds nothing in
474- // CI, or builds whatever version the file last named.
472+ // The workflow passes the tag it was started by. release.env is committed
473+ // now, so CI does have one — but a script that read only the file would
474+ // build whatever version the file last named, tag or no tag, and the file
475+ // and the pushed tag are two things that can disagree. The argument wins.
475476 script := readReleaseScript(t)
476477
477478 if !strings.Contains(script, `TAG="${1:-${TAG:-}}"`) {
@@ -469,9 +469,10 @@ func writeFile(t *testing.T, path, contents string) {
469 }469 }
470 470
471 func TestTheBuildScriptTakesTheTagFromTheCommandLine(t *testing.T) {471 func TestTheBuildScriptTakesTheTagFromTheCommandLine(t *testing.T) {
472- // release.env is git-ignored, so the workflow has none: it passes the tag472+ // The workflow passes the tag it was started by. release.env is committed
473- // it was started by. A script that only reads the file builds nothing in473+ // now, so CI does have one — but a script that read only the file would
474- // CI, or builds whatever version the file last named.474+ // build whatever version the file last named, tag or no tag, and the file
475+ // and the pushed tag are two things that can disagree. The argument wins.
475 script := readReleaseScript(t)476 script := readReleaseScript(t)
476 477
477 if !strings.Contains(script, `TAG="${1:-${TAG:-}}"`) {478 if !strings.Contains(script, `TAG="${1:-${TAG:-}}"`) {