diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2fe1d41621..469f28c508 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,8 @@ document will take precedence. ## Golang Resources -We use golang as our primary language for the development of OONI Probe CLI and do check out the resources below, quite useful to read before contributing. +We use golang as our primary language for the development of OONI Probe CLI and do +check out the resources below, quite useful to read before contributing. - [Effective Go](https://go.dev/doc/effective_go) - [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) @@ -81,6 +82,23 @@ is documented. At the minimum document all the exported symbols. Make sure you commit `go.mod` and `go.sum` changes. Make sure you run `go mod tidy` to minimize such changes. +## Version of Go + +OONI Probe release builds use a specific version Go. To make sure +you use the correct version of Go, please develop using: + +```bash +./script/go.bash +``` + +rather than using Go directly. This script is a drop-in replacement +for the `go` command that requires Go >= 1.15, downloads the correct +version of Go in `$HOME/sdk/go1.Y.Z`, and invokes it. + +By using the version of Go we'll be using for releasing, you make +sure that your contribution doesn't include functionality implemented +by later versions of Go. + ## Implementation requirements - always use `x/sys/execabs` or `./internal/shellx` instead of @@ -102,10 +120,9 @@ will understand you want to use the default pool) ## Code testing requirements -Make sure all tests pass with `go test -race ./...` run from the -top-level directory of this repository. (Running [netem]( -https://github.com/ooni/netem) based tests may not work as intended -with `-race` with macOS.) +Make sure all tests pass with `go test ./...` run from the +top-level directory of this repository. If you're using Linux, +please, run `go test -race ./...`. ## Writing a new OONI experiment @@ -118,50 +135,58 @@ not clear, please let us know during the review. To get a sense of what we expect from an experiment, see the [internal/tutorial]( https://github.com/ooni/probe-cli/tree/master/internal/tutorial) tutorial -## Branching and releasing - -The following diagram illustrates the overall branching and releasing -strategy loosely followed by the core team. If you are an external -contributor, you generally only care about the development part, which -is on the left-hand side of the diagram. - -![branching and releasing](docs/branching.png) - -Development uses the `master` branch. When we need to implement a -feature or fix a bug, we branch off of the `master` branch. We squash -and merge to include a feature or fix branch back into `master`. - -We periodically tag `-alpha` releases directly on `master`. The -semantics of such releases is that we reached a point where we have -features we would like to test using the `miniooni` research CLI -client. As part of these releases, we also update dependencies and -embedded assets. This process ensures that we perform better testing -of dependencies and assets as part of development. - -The `master` branch and pull requests only run CI lightweight tests -that ensure the code still compiles, has good coverage, and we are -not introducing regressions in terms of the measurement engine. - -To draft a release we branch off of `master` and create a `release/x.y` -branch where `x` is the major number and `y` is the minor number. For -release branches, we enable a very comprehensive set of tests that run -automatically with every commit. The purpose of a release branch is to -make sure all checks are green and hotfix bugs that we may discover -as part of more extensively testing a release candidate. Beta and stable -releases should occur on this branch. Subsequent patch releases should -also occur on this branch. We have one such branch for each `x.y` -release. If there are fixes on `master` that we want to backport, we -cherry-pick them into the release branch. Likewise, if we need to -forward port fixes, we cherry-pick them into `master`. When we backport, -the commit message should start with `[backport]`; when we forward -port, the commit message should start with `[forwardport]`. - -When we branch off release `x.y` from `master`, we also need to bump -the `alpha` version used by `master`. - -We build binary packages for each tagged release. We will use external -tools for publishing binaries to our Debian repository, Maven Central, etc. +## Branch management and releasing + +We integrate new features in the `master` branch. If you are an external +contributor, you generally only care about that. However, if you are +part of the OONI team, you also need to care about releasing. + +In terms of branching, the release process is roughly the following: + +1. we use the [routine sprint releases template]( +https://github.com/ooni/probe/blob/master/.github/ISSUE_TEMPLATE/routine-sprint-releases.md) +to create an issue describing the activities bound to an +upcoming OONI Probe release; + +2. the first part of the procedure happens inside the `master` branch +until we reach a point where we tag an `alpha` release (e.g., `v3.21.0-alpha`); + +3. once we have tagged an `alpha` release, we create and push a branch +named `release/X.Y` (e.g., `release/3.21`); + +4. we commit to the `master` branch and bump the `internal/version/version.go` +version number to be the next `alpha` release, such that we can distinguish +measurements from the `master` branch taken after tagging the `alpha`; + +5. we finish preparing the release and eventually tag a stable release +(e.g., `v3.21.0`) inside the `release/X.Y` branch; + +6. we keep the `release/X.Y` around forever and we keep it as the +branching point from which to create patch releases (e.g., `v.3.21.1`). + +The `release/X.Y` branches run many more CI checks than the `master` branch +and this allows us to ensure that everything is in order for releasing. We run +fewer checks in the `master` branch to make the development process leaner. + +We prefer backporting from `master` to `release/X.Y` to forward porting from +a `release/X.Y` to `master`. When backporting, the commit name should start +with `[backport]` to identify it as a backporting commit. + +## Releases + +Tagging causes specific GitHub Actions to create a pre-release (if the +tag contains `-alpha` or `-beta`) or a stable release (if the tag is like +`vX.Y.Z`; e.g., `v3.21.0`). + +Every night there is a GitHub Action that builds the current state of +the `master` branch and publishes it inside the [rolling release tag]( +https://github.com/ooni/probe-cli/releases/tag/rolling). + +We use a separate (private) repository to publish Android artefacts to +Maven Central, publish Debian packages, etc. ## Community Channels -Stuck somewhere or Have any questions? please join our [Slack Channels](https://slack.ooni.org/) or [IRC](ircs://irc.oftc.net:6697/#ooni). We're here to help and always available to discuss. +Stuck somewhere or Have any questions? please join our +[Slack Channels](https://slack.ooni.org/) or [IRC](ircs://irc.oftc.net:6697/#ooni). We're +here to help and always available to discuss. diff --git a/Readme.md b/Readme.md index a873aec016..f88f285a47 100644 --- a/Readme.md +++ b/Readme.md @@ -193,21 +193,13 @@ Please, see [CONTRIBUTING.md](CONTRIBUTING.md). SPDX-License-Identifier: GPL-3.0-or-later ``` -## Updating dependencies - -```bash -go get -t -u -v ./... && go mod tidy -``` - ## Releasing -Create an issue according to [the routine release template]( -https://github.com/ooni/probe/blob/master/.github/ISSUE_TEMPLATE/routine-sprint-releases.md) -and perform any item inside the check-list. - We build releases using [Makefile](Makefile), which requires GNU make. Run `make help` for detailed usage. +See also the relevant section of [CONTRIBUTING.md](CONTRIBUTING.md). + ## Semantic versioning policy The mobile library is a public package for technical reasons. Go mobile tools require diff --git a/docs/branching.excalidraw b/docs/branching.excalidraw deleted file mode 100644 index 5bd82c9e46..0000000000 --- a/docs/branching.excalidraw +++ /dev/null @@ -1,1599 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "type": "ellipse", - "version": 119, - "versionNonce": 1330344930, - "isDeleted": false, - "id": "FrOnFVoZdtaOFSxuuPxmW", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1408.3537069084748, - "y": 800.30078125, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 73.90624999999997, - "height": 73.640625, - "seed": 410580231, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-" - ] - }, - { - "type": "text", - "version": 143, - "versionNonce": 876589886, - "isDeleted": false, - "id": "9FCTh8g9toACPfN7yF2Tx", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1409.3693319084748, - "y": 766.171875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 68, - "height": 25, - "seed": 1086889555, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "master", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "arrow", - "version": 248, - "versionNonce": 2000070562, - "isDeleted": false, - "id": "ZsWo12aT76lV6R2H0b8V-", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1446.7307919303582, - "y": 950.9976346262545, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 3.298960021883431, - "height": 63.87654087625447, - "seed": 1443933405, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "i8LbwDXP7xJogP137mBcN", - "focus": 0.09728688754060083, - "gap": 5.964107779056704 - }, - "endBinding": { - "elementId": "FrOnFVoZdtaOFSxuuPxmW", - "focus": 0.12046082095303218, - "gap": 13.214645544914092 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -3.298960021883431, - -63.87654087625447 - ] - ] - }, - { - "type": "ellipse", - "version": 190, - "versionNonce": 983735166, - "isDeleted": false, - "id": "i8LbwDXP7xJogP137mBcN", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1412.9201131584748, - "y": 956.9453125, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65.4140625, - "height": 68.76953125, - "seed": 1779891677, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-", - "ErrLp--GEOsR3AU2FNwwz", - "9UArOcQdn2sGw8HZRdTn9", - "-4uRLR2_U4-S_frteL9z4", - "TT0_3mZZNKiBunuQSP-6q" - ] - }, - { - "type": "ellipse", - "version": 382, - "versionNonce": 721773410, - "isDeleted": false, - "id": "61hQjrW1eCfb5OIprSXq3", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1414.3498006584748, - "y": 1274.353515625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65.4140625, - "height": 68.76953125, - "seed": 1879178909, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-", - "ErrLp--GEOsR3AU2FNwwz", - "0dP3cEoktX25eCkvviNcM", - "SqX8Ci1x7CUCXJNH9loTM", - "1nUAY0kryU4ZLIvj0pXnc", - "8y35ZWVa5zFDh2Pz51UT-", - "WMUUsb8QMcD0Esl_zVVcA" - ] - }, - { - "type": "ellipse", - "version": 419, - "versionNonce": 2097052606, - "isDeleted": false, - "id": "H2rrZfUI5kDk2fa982pFA", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1555.8419881584748, - "y": 1264.396484375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65.4140625, - "height": 68.76953125, - "seed": 580711539, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-", - "ErrLp--GEOsR3AU2FNwwz", - "3c3zZZ8zVq7no-eT4hyXg", - "DeUB5-Hpy2FpWy-xPqJ1c" - ] - }, - { - "type": "arrow", - "version": 667, - "versionNonce": 889628450, - "isDeleted": false, - "id": "7IIG2hmA-CHb8UtlgutoE", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1125.3717557752195, - "y": 1516.549162785709, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 0.9791291618903415, - "height": 746.6889687780292, - "seed": 2143314653, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -0.9791291618903415, - -746.6889687780292 - ] - ] - }, - { - "type": "line", - "version": 465, - "versionNonce": 24400894, - "isDeleted": false, - "id": "EEe_kaxToCLeMN314Ayoi", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1103.8576131584748, - "y": 1522.23046875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 46.3359375, - "height": 1.34765625, - "seed": 2050861085, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 46.3359375, - -1.34765625 - ] - ] - }, - { - "type": "text", - "version": 698, - "versionNonce": 1034515170, - "isDeleted": false, - "id": "aavD3gXn3GoaVefLhge2J", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 4.715798234183623, - "x": 1085.2052694084748, - "y": 1175.91796875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 39, - "height": 25, - "seed": 417732371, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "time", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "arrow", - "version": 581, - "versionNonce": 1644504126, - "isDeleted": false, - "id": "0dP3cEoktX25eCkvviNcM", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1445.8941570710285, - "y": 1425.1896146421564, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 1.4090253251076774, - "height": 75.08235428431271, - "seed": 1132001171, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "_2_7auHWgP9OSMdW-IMqi", - "focus": -0.008815902175433654, - "gap": 2.850118004216746 - }, - "endBinding": { - "elementId": "61hQjrW1eCfb5OIprSXq3", - "focus": 0.10234482780286448, - "gap": 7.070910919200607 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -1.4090253251076774, - -75.08235428431271 - ] - ] - }, - { - "type": "ellipse", - "version": 330, - "versionNonce": 125617826, - "isDeleted": false, - "id": "_2_7auHWgP9OSMdW-IMqi", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1414.1740194084748, - "y": 1428.025390625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65.4140625, - "height": 68.76953125, - "seed": 1207426259, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-", - "ErrLp--GEOsR3AU2FNwwz", - "0dP3cEoktX25eCkvviNcM", - "SqX8Ci1x7CUCXJNH9loTM" - ] - }, - { - "type": "arrow", - "version": 328, - "versionNonce": 1351740542, - "isDeleted": false, - "id": "SqX8Ci1x7CUCXJNH9loTM", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1483.1623006584748, - "y": 1446.53515625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 79.88293214663872, - "height": 99.1479660904406, - "seed": 563908051, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "_2_7auHWgP9OSMdW-IMqi", - "focus": 0.5480446646136934, - "gap": 6.638688544200527 - }, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - 79.88293214663872, - -99.1479660904406 - ] - ] - }, - { - "type": "ellipse", - "version": 315, - "versionNonce": 724542050, - "isDeleted": false, - "id": "s6P4OqGNKJFw1EDYtmZZv", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1552.2091756584748, - "y": 962.474609375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65.4140625, - "height": 68.76953125, - "seed": 878492787, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-", - "ErrLp--GEOsR3AU2FNwwz", - "3c3zZZ8zVq7no-eT4hyXg", - "DKJsQnJQP6zamLM3YcUgM", - "E89OFYWHnyapVNraQK6pF", - "9d9CMdbxWDQ158maCuq2K" - ] - }, - { - "type": "text", - "version": 199, - "versionNonce": 450604222, - "isDeleted": false, - "id": "E3oEt7YrddzXwWfuXo2BN", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1525.5490194084748, - "y": 924.55859375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 113, - "height": 25, - "seed": 1670410451, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "release/3.4", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "rectangle", - "version": 245, - "versionNonce": 246764094, - "isDeleted": false, - "id": "SeebVefCHR0BG_Msq_mBX", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1623.8185506584748, - "y": 1004.05859375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 74.2987929059682, - "height": 28.08984375, - "seed": 781280467, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "GO0tq3-qTL5xGa4FqNPel" - ] - }, - { - "type": "text", - "version": 200, - "versionNonce": 780363006, - "isDeleted": false, - "id": "vzC_reXHu0W5D5Vdy7wzo", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1639.3262379777896, - "y": 1009.2944701526376, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 43, - "height": 17, - "seed": 1846516307, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 14.094472755782043, - "fontFamily": 1, - "text": "v3.4.0", - "baseline": 12, - "textAlign": "center", - "verticalAlign": "middle" - }, - { - "type": "ellipse", - "version": 472, - "versionNonce": 2039476706, - "isDeleted": false, - "id": "_BzjrIXl7qYcDggInAePz", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1416.0451131584748, - "y": 1106.623046875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65.4140625, - "height": 68.76953125, - "seed": 1497777075, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-", - "ErrLp--GEOsR3AU2FNwwz", - "1nUAY0kryU4ZLIvj0pXnc", - "DKJsQnJQP6zamLM3YcUgM", - "-4uRLR2_U4-S_frteL9z4" - ] - }, - { - "type": "arrow", - "version": 70, - "versionNonce": 487200062, - "isDeleted": false, - "id": "1nUAY0kryU4ZLIvj0pXnc", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1446.2091756584748, - "y": 1264.625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 0.0234375, - "height": 87.6484375, - "seed": 2110933469, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "61hQjrW1eCfb5OIprSXq3", - "focus": -0.026277293582462318, - "gap": 9.737311460875041 - }, - "endBinding": { - "elementId": "_BzjrIXl7qYcDggInAePz", - "focus": 0.07673924794852657, - "gap": 1.6809069551271776 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - 0.0234375, - -87.6484375 - ] - ] - }, - { - "type": "arrow", - "version": 39, - "versionNonce": 540763554, - "isDeleted": false, - "id": "9UArOcQdn2sGw8HZRdTn9", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1446.8732381584748, - "y": 1107.04296875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 1.85546875, - "height": 75.97265625, - "seed": 1363842525, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": null, - "endBinding": { - "elementId": "i8LbwDXP7xJogP137mBcN", - "focus": 0.04829005202176653, - "gap": 5.360559841423914 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -1.85546875, - -75.97265625 - ] - ] - }, - { - "type": "ellipse", - "version": 591, - "versionNonce": 533773694, - "isDeleted": false, - "id": "VXTr4t2TCfsx3lBbrX9FA", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1558.6388631584748, - "y": 1094.869140625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65.4140625, - "height": 68.76953125, - "seed": 442745331, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "ZsWo12aT76lV6R2H0b8V-", - "ErrLp--GEOsR3AU2FNwwz", - "1nUAY0kryU4ZLIvj0pXnc", - "DKJsQnJQP6zamLM3YcUgM", - "8y35ZWVa5zFDh2Pz51UT-", - "DeUB5-Hpy2FpWy-xPqJ1c", - "E89OFYWHnyapVNraQK6pF", - "TT0_3mZZNKiBunuQSP-6q" - ] - }, - { - "type": "arrow", - "version": 58, - "versionNonce": 281174370, - "isDeleted": false, - "id": "DeUB5-Hpy2FpWy-xPqJ1c", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1587.3380819084748, - "y": 1261.33203125, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 0.625, - "height": 93.7421875, - "seed": 248883293, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "H2rrZfUI5kDk2fa982pFA", - "focus": -0.044656571726164086, - "gap": 3.085899264298419 - }, - "endBinding": { - "elementId": "VXTr4t2TCfsx3lBbrX9FA", - "focus": 0.09561067905754547, - "gap": 4.113949074597102 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - 0.625, - -93.7421875 - ] - ] - }, - { - "type": "arrow", - "version": 61, - "versionNonce": 471358910, - "isDeleted": false, - "id": "E89OFYWHnyapVNraQK6pF", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1590.7833944084748, - "y": 1090.12109375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 2.5, - "height": 54.69140625, - "seed": 1555295773, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "VXTr4t2TCfsx3lBbrX9FA", - "focus": 0.03745027340171186, - "gap": 4.7524583668077724 - }, - "endBinding": { - "elementId": "s6P4OqGNKJFw1EDYtmZZv", - "focus": -0.048987941378323296, - "gap": 4.345762088088847 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -2.5, - -54.69140625 - ] - ] - }, - { - "type": "rectangle", - "version": 663, - "versionNonce": 376694050, - "isDeleted": false, - "id": "_LhK1JP2uBFu9cs14lXrK", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1296.482585787164, - "y": 1457.548828125, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 109.40816790596809, - "height": 28.898437499999996, - "seed": 1155306515, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [] - }, - { - "type": "text", - "version": 369, - "versionNonce": 654439934, - "isDeleted": false, - "id": "KvB7SKO8PrwXdeyL73xr_", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1301.186669740148, - "y": 1463.498046875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 100, - "height": 17, - "seed": 1945414301, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 14.094472755782043, - "fontFamily": 1, - "text": "v3.4.0-alpha.2", - "baseline": 12, - "textAlign": "center", - "verticalAlign": "middle" - }, - { - "type": "rectangle", - "version": 423, - "versionNonce": 2014368482, - "isDeleted": false, - "id": "-glBvfuqfOWMmoU9gXRFT", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1631.840966615148, - "y": 1279.462890625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 89.32223040596818, - "height": 28.3203125, - "seed": 290301587, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "5ga8yTO8PWQUQYLeZ_f6b" - ] - }, - { - "type": "text", - "version": 307, - "versionNonce": 1912351678, - "isDeleted": false, - "id": "nrPdO2GBc4d1bH82trixr", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1636.0020818181322, - "y": 1285.123046875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 81, - "height": 17, - "seed": 817102877, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "5ga8yTO8PWQUQYLeZ_f6b" - ], - "fontSize": 14.094472755782043, - "fontFamily": 1, - "text": "v3.4.0-beta", - "baseline": 12, - "textAlign": "center", - "verticalAlign": "middle" - }, - { - "type": "text", - "version": 179, - "versionNonce": 1492545506, - "isDeleted": false, - "id": "VSB6KRjDrKaaQgIKYbm0R", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 5.4044502562560535, - "x": 1474.806831908475, - "y": 1379.625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 61, - "height": 25, - "seed": 1175433267, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "branch", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "rectangle", - "version": 343, - "versionNonce": 1812888190, - "isDeleted": false, - "id": "l56iGD3sn2wE1jpAe4ahC", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1935.5021444084748, - "y": 963.30859375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 116.50781250000023, - "height": 88.8671875, - "seed": 1978032861, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "GO0tq3-qTL5xGa4FqNPel" - ] - }, - { - "type": "text", - "version": 289, - "versionNonce": 322050082, - "isDeleted": false, - "id": "BLCZtWmQ6-ehPzhO-L9au", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1958.256050658475, - "y": 982.7421875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 71, - "height": 50, - "seed": 654630909, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "binary\nrelease", - "baseline": 43, - "textAlign": "center", - "verticalAlign": "middle" - }, - { - "type": "text", - "version": 386, - "versionNonce": 45380350, - "isDeleted": false, - "id": "tkm3e2izHwHNnA8Lcc5WG", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1796.8693319084748, - "y": 991.0625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 101, - "height": 50, - "seed": 1910496637, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "CI build &\npublish", - "baseline": 43, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "text", - "version": 254, - "versionNonce": 2036443938, - "isDeleted": false, - "id": "m1Xhg8wN1xso2OXh8pOyU", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1280.1310506584748, - "y": 690.71484375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 702.3518750000002, - "height": 38.42187500000003, - "seed": 540380669, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 30.73750000000001, - "fontFamily": 1, - "text": "=[ Ideal ooni/probe-cli development process ]=", - "baseline": 27.42187500000003, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "arrow", - "version": 129, - "versionNonce": 512454846, - "isDeleted": false, - "id": "WMUUsb8QMcD0Esl_zVVcA", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1417.2990194084748, - "y": 1274.5234375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 150.6173141923548, - "height": 85.24313437528917, - "seed": 367157373, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "61hQjrW1eCfb5OIprSXq3", - "focus": 0.4448864992719663, - "gap": 11.703208740334766 - }, - "endBinding": { - "elementId": "t8m7A_AiI0Zz6g-q3XhnP", - "focus": 0.8748653796977708, - "gap": 14.676496192619688 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -150.6173141923548, - -85.24313437528917 - ] - ] - }, - { - "type": "ellipse", - "version": 183, - "versionNonce": 1991213602, - "isDeleted": false, - "id": "t8m7A_AiI0Zz6g-q3XhnP", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1208.2599569084748, - "y": 1098.05078125, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 77.91796875, - "height": 80.2890625, - "seed": 205241949, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "70dbl4jJzrLBtDEytNCQV", - "WMUUsb8QMcD0Esl_zVVcA" - ] - }, - { - "type": "arrow", - "version": 365, - "versionNonce": 798664958, - "isDeleted": false, - "id": "70dbl4jJzrLBtDEytNCQV", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1247.6935506584748, - "y": 1097.83203125, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 1.41015625, - "height": 67.89453125, - "seed": 1082596541, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "t8m7A_AiI0Zz6g-q3XhnP", - "focus": 0.03369303215762137, - "gap": 1 - }, - "endBinding": { - "elementId": "cbY7dAu_xBZLtfnwANQ0h", - "focus": 0.02205392272987631, - "gap": 2.894614565986096 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -1.41015625, - -67.89453125 - ] - ] - }, - { - "type": "ellipse", - "version": 171, - "versionNonce": 729738722, - "isDeleted": false, - "id": "cbY7dAu_xBZLtfnwANQ0h", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1208.3615194084748, - "y": 960.5625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 76.01953124999999, - "height": 66.48046875000001, - "seed": 92260445, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "70dbl4jJzrLBtDEytNCQV", - "-4uRLR2_U4-S_frteL9z4" - ] - }, - { - "type": "text", - "version": 129, - "versionNonce": 43571518, - "isDeleted": false, - "id": "pvblHfogurhXv88mbBcRK", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1190.8966756584748, - "y": 923.8671875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 97, - "height": 25, - "seed": 555034749, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "issue/NNN", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "text", - "version": 210, - "versionNonce": 854253986, - "isDeleted": false, - "id": "l5V8BKWT6NL8Pot9eGQxW", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0.5019114078121252, - "x": 1305.6271444084748, - "y": 1239.46875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 61, - "height": 25, - "seed": 1943628413, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "branch", - "baseline": 18, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "arrow", - "version": 477, - "versionNonce": 1860632958, - "isDeleted": false, - "id": "-4uRLR2_U4-S_frteL9z4", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 2, - "opacity": 100, - "angle": 0.004286381490581803, - "x": 1281.456370622558, - "y": 1027.6261866542388, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 134.43973816675407, - "height": 87.48529746818951, - "seed": 515639315, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "cbY7dAu_xBZLtfnwANQ0h", - "focus": 0.2493704175711463, - "gap": 13.087600935174486 - }, - "endBinding": { - "elementId": "_BzjrIXl7qYcDggInAePz", - "focus": 0.09625345211262865, - "gap": 8.481964629522814 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - 134.43973816675407, - 87.48529746818951 - ] - ] - }, - { - "type": "text", - "version": 487, - "versionNonce": 404905314, - "isDeleted": false, - "id": "uF9xy7cXMn1FvZunqydoW", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 2, - "opacity": 100, - "angle": 0.6085681160569036, - "x": 1295.7169881584748, - "y": 1039.40625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 92, - "height": 50, - "seed": 1420693821, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [ - "-4uRLR2_U4-S_frteL9z4" - ], - "fontSize": 20, - "fontFamily": 1, - "text": "squash &\nmerge", - "baseline": 43, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "arrow", - "version": 211, - "versionNonce": 678715682, - "isDeleted": false, - "id": "TT0_3mZZNKiBunuQSP-6q", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1555.6427694084748, - "y": 1114.3515625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 91.1191404562444, - "height": 83.38521337099382, - "seed": 1441302717, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "startBinding": { - "elementId": "VXTr4t2TCfsx3lBbrX9FA", - "focus": -0.38981301814327424, - "gap": 5.744985949842281 - }, - "endBinding": { - "elementId": "i8LbwDXP7xJogP137mBcN", - "focus": 0.49013243946634244, - "gap": 9.849649250656697 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -91.1191404562444, - -83.38521337099382 - ] - ] - }, - { - "type": "text", - "version": 251, - "versionNonce": 274151934, - "isDeleted": false, - "id": "u4he9DEv2RkSQWCHnrB1f", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 2, - "opacity": 100, - "angle": 0.8031270324586943, - "x": 1496.6896444084748, - "y": 1059.35546875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 57, - "height": 50, - "seed": 1349313139, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "cherry\npick", - "baseline": 43, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "type": "rectangle", - "version": 756, - "versionNonce": 793767138, - "isDeleted": false, - "id": "sHsXEtwWTjBFom2nIhGIs", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1289.2511854554907, - "y": 820.90625, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 109.40816790596809, - "height": 28.898437499999996, - "seed": 507648189, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [] - }, - { - "type": "text", - "version": 468, - "versionNonce": 530270782, - "isDeleted": false, - "id": "0dgfZ8refzUdb0GHOjr_F", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1301.4552694084748, - "y": 826.85546875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 85, - "height": 17, - "seed": 1897307539, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 14.094472755782043, - "fontFamily": 1, - "text": "v3.5.0-alpha", - "baseline": 12, - "textAlign": "center", - "verticalAlign": "middle" - }, - { - "type": "rectangle", - "version": 378, - "versionNonce": 121553890, - "isDeleted": false, - "id": "q7DClrWmyGxwfXjKy2XJJ", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1935.5021444084748, - "y": 1258.234375, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 116.50781250000023, - "height": 88.8671875, - "seed": 1763826146, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [] - }, - { - "type": "text", - "version": 325, - "versionNonce": 602497854, - "isDeleted": false, - "id": "pslagGm6vRdPKOM8BCcfC", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1958.2560506584753, - "y": 1277.66796875, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 71, - "height": 50, - "seed": 367701310, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "binary\nrelease", - "baseline": 43, - "textAlign": "center", - "verticalAlign": "middle" - }, - { - "type": "text", - "version": 426, - "versionNonce": 1950349218, - "isDeleted": false, - "id": "2P11PhMCZn3Ro5kFyBNif", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 1796.8693319084748, - "y": 1273.98828125, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 101, - "height": 50, - "seed": 357584290, - "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], - "fontSize": 20, - "fontFamily": 1, - "text": "CI build &\npublish", - "baseline": 43, - "textAlign": "center", - "verticalAlign": "top" - }, - { - "id": "GO0tq3-qTL5xGa4FqNPel", - "type": "arrow", - "x": 1712.7208944084748, - "y": 1015.0400870045719, - "width": 213.9921875, - "height": 1.661370673197439, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#ffffff", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1208219362, - "version": 174, - "versionNonce": 1939241662, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 213.9921875, - 1.661370673197439 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "SeebVefCHR0BG_Msq_mBX", - "focus": -0.24184310980097481, - "gap": 14.603550844031815 - }, - "endBinding": { - "elementId": "l56iGD3sn2wE1jpAe4ahC", - "focus": -0.211197282114048, - "gap": 8.789062500000114 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "5ga8yTO8PWQUQYLeZ_f6b", - "type": "arrow", - "x": 1730.8732381584748, - "y": 1299.8515625, - "width": 205.75, - "height": 0.54296875, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#ffffff", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1249050814, - "version": 101, - "versionNonce": 1516548962, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 205.75, - -0.54296875 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "nrPdO2GBc4d1bH82trixr", - "focus": 0.7403380580231628, - "gap": 13.871156340342623 - }, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - }, - "files": {} -} \ No newline at end of file diff --git a/docs/branching.png b/docs/branching.png deleted file mode 100644 index d8e48f171e..0000000000 Binary files a/docs/branching.png and /dev/null differ