diff --git a/docs/index.md b/docs/index.md index 37c00b14..8a3e308f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,6 +12,7 @@ Most FarmBot development/testing is done on a standard desktop PC. * [Developing on your local PC](/docs/host_development/host_development.md) * [Deploying on Raspberry Pi](/docs/target_development/building_target_firmware.md) + * [Provisioning OTA system](/docs/target_development/provisioning_ota_system.md) * [Publishing Firmware (OTAs)](/docs/target_development/releasing_target_firmware.md) * [Why doesn't my device boot after building firmware](docs/target_development/target_faq.md) * [Inspecting a running devicve](/docs/target_development/consoles/target_console.md) diff --git a/docs/target_development/provisioning_ota_system.md b/docs/target_development/provisioning_ota_system.md new file mode 100644 index 00000000..d67b9ab7 --- /dev/null +++ b/docs/target_development/provisioning_ota_system.md @@ -0,0 +1,195 @@ +# Provisioning the Release System + +Publishing a FarmBotOS release requires coordination of a few different systems. + +* FarmBot Web App +* FarmBot OS +* NervesHub +* CircleCI +* GitHub branches and releases + +## Legacy Release System + +The legacy system is somewhat simpiler. It goes as follows: + +### Pull request into `master` branch + +```bash +git checkout master +git merge staging +git push origin master +``` + +Obviously this will not actually work because of testing and things, but that +is what happens behind the scenes on GitHub. + +### CircleCI builds release + +Once merged into master CircleCI will create a `draft` release on GitHub. This +must be QA'd and confirmed manually before publishing. Once published, FarmBot +will check the `OS_AUTO_UPDATE_URL` in the JWT. + +### Beta updates + +Users may opt into beta updates by settings `os_beta_updates: true` on their +device's `FbosConfig` endpoint. + +Beta releases are constructed by creating a tag off of the `staging` branch. + +1) update `VERSION`. + Should follow `X.Y.Z-rcN` + +2) update `CHANGELOG.md`. + Topmost version should contain: `vX.Y.Z` + +3) Commit release. + Message should follow format: `Release vX.Y.Z-rcN` + +4) push `staging` + `git push origin staging` + +5) tag + `git tag v$(cat VERSION)` + `git push origin v$(cat VERSION)` + +## NervesHub System + +The NervesHub system is simpiler to use, but more complex to setup. + +### User registration + +Create a admin user. This should be the same `ADMIN_EMAIL` used in +the WebApp configuration. + +```bash +mix nerves_hub.user register +Email address: admin@farmbot.io +Name: farmbot +NervesHub password: *super secret* +Local password: *super duper secret* +``` + +```bash +mix nerves_hub.product create +name: farmbot +Local password: *super duper secret* +``` + +### Signing keys + +Now a choice will need to be made. + +If fwup signing keys existed beforehand (they did for FarmBot Inc) do: + +```bash +mix nerves_hub.key import +Local password: *super duper secret* +``` + +If new keys are required (probably named "prod") do: + +```bash +mix nerves_hub.key create +Local password: *super duper secret* +``` + +### Exporting certs and keys + +The API and CI need copies of these keys and certs. +These certs need to be updated before they expire. By default they are good for +1 year + +```bash +mix nerves_hub.user cert export +Local password: *super duper secret* +User certs exported to: +tar -xf -C nerves-hub/ +``` + +```bash +mix nerves_hub.key export prod +Local password: *super duper secret* +Fwup keys exported to: +tar -xf -C nerves-hub/ +``` + +You will also need the CA cert bundle for the WebApp: +(this may only work for BASH) + +```bash +REPO_URL=https://raw.githubusercontent.com/nerves-hub/nerves_hub_cli/master/priv/master/priv/ca_certs +{ \ + curl -s $REPO_URL/root-ca.pem | head -20 \ +&& curl -s $REPO_URL/intermediate-server-ca.pem | head -20 \ +&& curl -s $REPO_URL/intermediate-user-ca.pem | head -20; \ +} > nerves-hub/nerves-hub-ca-certs.pem +``` + +Now the FarmBot API needs the values of in it's environment: + +* `NERVES_HUB_KEY` -> + `heroku config:set NERVES_HUB_KEY="$(cat nerves-hub/key.pem)" --app $APP` +* `NERVES_HUB_CERT` -> + `heroku config:set NERVES_HUB_CERT="$(cat nerves-hub/cert.pem)" --app $APP` +* `NERVES_HUB_CA` -> + `heroku config:set NERVES_HUB_CA="$(cat nerves-hub/ca.pem)" --app $APP` + +CircleCI will need: + +* `NERVES_HUB_KEY` -> `base64 $(cat nerves-hub/key.pem)` +* `NERVES_HUB_CERT` -> `base64 $(cat nerves-hub/cert.pem)` +* `NERVES_HUB_FW_PRIVATE_KEY` -> `base64 $(cat nerves-hub/.priv)` +* `NERVES_HUB_FW_PUBLIC_KEY` -> `base64 $(cat nerves-hub/.pub)` + +### Provisioning and Tags + +Tags/Deployments follow this structure: + +```json +[ + "application:", + "channel:" +] +``` + +NOTE: the tags **NOT** json objects, they are simple strings +split by a `:` character. This is done _only_ for readability. + +where `MIX_ENV` will be one of: + +* `dev` +* `prod` + +and `CHANNEL` will be one of: + +* `beta` +* `stable` + +There should be at least one deployment matching the following +tags: + +* `["application:dev", "channel:stable"]` + a development FBOS release on the `stable` channel +* `["application:prod", "channel:stable"]` + a production FBOS release on the `stable` channel +* `["application:dev", "channel:beta"]` + a development FBOS release on the `beta` channel +* `["application:prod", "channel:beta"]` + a production FBOS release on the `beta` channel +* `["application:dev", "channel:stable"]` + a development FBOS release on the `stable` channel +* `["application:prod", "channel:stable"]` + a production FBOS release on the `stable` channel +* `["application:dev", "channel:beta"]` + a development FBOS release on the `beta` channel +* `["application:prod", "channel:beta"]` + a production FBOS release on the `beta` channel + +### First time setup + +```bash +heroku config:set NERVES_HUB_CERT="$NERVES_HUB_CERT" --app=$HEROKU_APPNAME +heroku config:set NERVES_HUB_KEY="$NERVES_HUB_KEY" --app=$HEROKU_APPNAME +heroku config:set NERVES_HUB_CA="$NERVES_HUB_CA" --app=$HEROKU_APPNAME +heroku config:set NERVES_HUB_ORG="$NERVES_HUB_ORG" --app=$HEROKU_APPNAME +``` diff --git a/docs/target_development/releasing_target_firmware.md b/docs/target_development/releasing_target_firmware.md index d67b9ab7..63360ab0 100644 --- a/docs/target_development/releasing_target_firmware.md +++ b/docs/target_development/releasing_target_firmware.md @@ -1,195 +1,35 @@ -# Provisioning the Release System +# Publishing OTAs -Publishing a FarmBotOS release requires coordination of a few different systems. +## Beta -* FarmBot Web App -* FarmBot OS -* NervesHub -* CircleCI -* GitHub branches and releases - -## Legacy Release System - -The legacy system is somewhat simpiler. It goes as follows: - -### Pull request into `master` branch +Publish an OTA to the `beta` channel can be done by: ```bash -git checkout master -git merge staging -git push origin master +./scripts/release_candidate.sh ``` -Obviously this will not actually work because of testing and things, but that -is what happens behind the scenes on GitHub. +## QA -### CircleCI builds release - -Once merged into master CircleCI will create a `draft` release on GitHub. This -must be QA'd and confirmed manually before publishing. Once published, FarmBot -will check the `OS_AUTO_UPDATE_URL` in the JWT. - -### Beta updates - -Users may opt into beta updates by settings `os_beta_updates: true` on their -device's `FbosConfig` endpoint. - -Beta releases are constructed by creating a tag off of the `staging` branch. - -1) update `VERSION`. - Should follow `X.Y.Z-rcN` - -2) update `CHANGELOG.md`. - Topmost version should contain: `vX.Y.Z` - -3) Commit release. - Message should follow format: `Release vX.Y.Z-rcN` - -4) push `staging` - `git push origin staging` - -5) tag - `git tag v$(cat VERSION)` - `git push origin v$(cat VERSION)` - -## NervesHub System - -The NervesHub system is simpiler to use, but more complex to setup. - -### User registration - -Create a admin user. This should be the same `ADMIN_EMAIL` used in -the WebApp configuration. +Publish an OTA to the `qa` channel can be done by pushing a new branch +to github with `qa/` prefix. ```bash -mix nerves_hub.user register -Email address: admin@farmbot.io -Name: farmbot -NervesHub password: *super secret* -Local password: *super duper secret* +git checkout -b qa/ +git push origin qa/ ``` +## Production + +Publish an OTA to the `stable` channel can be done by: + ```bash -mix nerves_hub.product create -name: farmbot -Local password: *super duper secret* -``` - -### Signing keys - -Now a choice will need to be made. - -If fwup signing keys existed beforehand (they did for FarmBot Inc) do: - -```bash -mix nerves_hub.key import -Local password: *super duper secret* -``` - -If new keys are required (probably named "prod") do: - -```bash -mix nerves_hub.key create -Local password: *super duper secret* -``` - -### Exporting certs and keys - -The API and CI need copies of these keys and certs. -These certs need to be updated before they expire. By default they are good for -1 year - -```bash -mix nerves_hub.user cert export -Local password: *super duper secret* -User certs exported to: -tar -xf -C nerves-hub/ -``` - -```bash -mix nerves_hub.key export prod -Local password: *super duper secret* -Fwup keys exported to: -tar -xf -C nerves-hub/ -``` - -You will also need the CA cert bundle for the WebApp: -(this may only work for BASH) - -```bash -REPO_URL=https://raw.githubusercontent.com/nerves-hub/nerves_hub_cli/master/priv/master/priv/ca_certs -{ \ - curl -s $REPO_URL/root-ca.pem | head -20 \ -&& curl -s $REPO_URL/intermediate-server-ca.pem | head -20 \ -&& curl -s $REPO_URL/intermediate-user-ca.pem | head -20; \ -} > nerves-hub/nerves-hub-ca-certs.pem -``` - -Now the FarmBot API needs the values of in it's environment: - -* `NERVES_HUB_KEY` -> - `heroku config:set NERVES_HUB_KEY="$(cat nerves-hub/key.pem)" --app $APP` -* `NERVES_HUB_CERT` -> - `heroku config:set NERVES_HUB_CERT="$(cat nerves-hub/cert.pem)" --app $APP` -* `NERVES_HUB_CA` -> - `heroku config:set NERVES_HUB_CA="$(cat nerves-hub/ca.pem)" --app $APP` - -CircleCI will need: - -* `NERVES_HUB_KEY` -> `base64 $(cat nerves-hub/key.pem)` -* `NERVES_HUB_CERT` -> `base64 $(cat nerves-hub/cert.pem)` -* `NERVES_HUB_FW_PRIVATE_KEY` -> `base64 $(cat nerves-hub/.priv)` -* `NERVES_HUB_FW_PUBLIC_KEY` -> `base64 $(cat nerves-hub/.pub)` - -### Provisioning and Tags - -Tags/Deployments follow this structure: - -```json -[ - "application:", - "channel:" -] -``` - -NOTE: the tags **NOT** json objects, they are simple strings -split by a `:` character. This is done _only_ for readability. - -where `MIX_ENV` will be one of: - -* `dev` -* `prod` - -and `CHANNEL` will be one of: - -* `beta` -* `stable` - -There should be at least one deployment matching the following -tags: - -* `["application:dev", "channel:stable"]` - a development FBOS release on the `stable` channel -* `["application:prod", "channel:stable"]` - a production FBOS release on the `stable` channel -* `["application:dev", "channel:beta"]` - a development FBOS release on the `beta` channel -* `["application:prod", "channel:beta"]` - a production FBOS release on the `beta` channel -* `["application:dev", "channel:stable"]` - a development FBOS release on the `stable` channel -* `["application:prod", "channel:stable"]` - a production FBOS release on the `stable` channel -* `["application:dev", "channel:beta"]` - a development FBOS release on the `beta` channel -* `["application:prod", "channel:beta"]` - a production FBOS release on the `beta` channel - -### First time setup - -```bash -heroku config:set NERVES_HUB_CERT="$NERVES_HUB_CERT" --app=$HEROKU_APPNAME -heroku config:set NERVES_HUB_KEY="$NERVES_HUB_KEY" --app=$HEROKU_APPNAME -heroku config:set NERVES_HUB_CA="$NERVES_HUB_CA" --app=$HEROKU_APPNAME -heroku config:set NERVES_HUB_ORG="$NERVES_HUB_ORG" --app=$HEROKU_APPNAME -``` +git checkout -b rel- +# update VERSION +# update CHANGELOG.md +# update README.md +git commit -am "Release v" +git push origin rel- +# open pull request +# merge pull request +# publish release once CI has completed +``` \ No newline at end of file