From 24431bcaabe9e6e7f70ebabb67e6b901934e036f Mon Sep 17 00:00:00 2001 From: Daniel Constantin Date: Thu, 13 Jun 2019 21:37:23 +0300 Subject: [PATCH] Set-up Continuous Deployment (#513) --- .travis.yml | 14 ++++ README.md | 36 ++++++++-- docs-internal/Continuous-deployment.md | 47 ++++++++++++ docs-internal/Continuous-integration.md | 4 +- docs-internal/Releasing.md | 68 ++++++++++++++++++ docs-internal/next/Specification.md | 4 +- lerna.json | 7 +- package.json | 3 +- packages/aragon-cli/package.json | 2 +- packages/e2e-tests/src/cli/run.test.js.md | 8 +-- packages/e2e-tests/src/cli/run.test.js.snap | Bin 1898 -> 1901 bytes .../src/create-aragon-app/index.test.js | 2 +- 12 files changed, 177 insertions(+), 18 deletions(-) create mode 100644 docs-internal/Continuous-deployment.md create mode 100644 docs-internal/Releasing.md diff --git a/.travis.yml b/.travis.yml index 465bcd68b..f40ab3716 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,3 +17,17 @@ script: - travis_wait 30 npm run test:e2e after_success: - npm run report-coverage +before_deploy: + - echo 'Preparing to deploy to NPM' + - echo 'Cleaning any uncommitted changes' + - echo 'git --no-pager diff' + - git stash + - echo 'Setting up the npm auth token' + - echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" >> $HOME/.npmrc +deploy: + skip_cleanup: true + provider: script + script: 'npm run publish:nightly' + on: + node_js: '11' + tags: true diff --git a/README.md b/README.md index 4cbebea6f..b8e00027f 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,35 @@ -# aragonCLI Basic Overview +# aragonCLI -The aragonCLI (Command Line Interface) is used to create and develop Aragon apps. +The aragonCLI (Command Line Interface) is used to create and develop Aragon Apps, as well as to +interact with DAOs (create, install apps, inspect permissions, etc.). -| Package | Version | Downloads | -| ----------------------- | --------- | ----------- | -| `@aragon/cli` | [![NPM version](https://img.shields.io/npm/v/@aragon/cli.svg?style=flat-square)](https://npmjs.org/package/@aragon/cli) | [![Downloads](https://img.shields.io/npm/dm/@aragon/cli.svg?style=flat-square)](https://npmjs.org/package/@aragon/cli) | -| `create-aragon-app` | [![NPM version](https://img.shields.io/npm/v/create-aragon-app.svg?style=flat-square)](https://npmjs.org/package/create-aragon-app) | [![Downloads](https://img.shields.io/npm/dm/create-aragon-app.svg?style=flat-square)](https://npmjs.org/package/create-aragon-app) | +## Nightly builds + +Nightly builds may contain features in their early stages, expect things to break! + +**Get a sneak peek at the next version of the CLI, and help us making it better in the process!** +**Please try it out and let us know early and often if you find any bugs or regressions. Thanks!** + +```sh +npm install @aragon/cli@nightly +``` + +## Stable builds + +Periodically, after some testing has been done, we mark `nightly` builds as `stable`. +This build is recommended to most people, especially devs that are getting started and not familiar +with the stack, or anyone who values stability over the bleeding-edge features. + +```sh +npm install @aragon/cli +``` + +## Package overview + +| Package | Version (latest/stable) | Version (nightly) | Downloads | +| ------- | ----------------------- | ----------------- | --------- | +| `@aragon/cli` | [![NPM version](https://img.shields.io/npm/v/@aragon/cli/latest.svg?style=flat-square)](https://npmjs.org/package/@aragon/cli) | [![NPM version](https://img.shields.io/npm/v/@aragon/cli/nightly.svg?style=flat-square)](https://npmjs.org/package/@aragon/cli) | [![Downloads](https://img.shields.io/npm/dm/@aragon/cli.svg?style=flat-square)](https://npmjs.org/package/@aragon/cli) | +| `create-aragon-app` | [![NPM version](https://img.shields.io/npm/v/create-aragon-app/latest.svg?style=flat-square)](https://npmjs.org/package/create-aragon-app) | [![NPM version](https://img.shields.io/npm/v/create-aragon-app/nightly.svg?style=flat-square)](https://npmjs.org/package/create-aragon-app) | [![Downloads](https://img.shields.io/npm/dm/create-aragon-app.svg?style=flat-square)](https://npmjs.org/package/create-aragon-app) | diff --git a/docs-internal/Continuous-deployment.md b/docs-internal/Continuous-deployment.md new file mode 100644 index 000000000..81410b0c0 --- /dev/null +++ b/docs-internal/Continuous-deployment.md @@ -0,0 +1,47 @@ +# Continuous Deployment + +Having CD configured in an automated way, allows us to: + +- make the release task less time-consuming and less prone to human errors +- decrease the attack surface by not needing maintainers to have publish access + +## Setup + +### Travis CI + +The configuration file is located at `.travis.yml`. + +Requirements: this configuration assumes a `NPM_TOKEN` environment variable defined in Travis's +settings. (see [travis docs about env vars][travis-docs-env-vars]) + +Notes: + +- `before_deploy` + + This hook runs after the build and testing steps have finished, and is purpose is twofold: + + 1. Clean-up uncommitted changes resulted from installing or building, e.g.: lockfiles + 2. Grant the `npm` agent publish access + +- `deploy` + + The deploy step uses lerna to publish packages that have been released, but not deployed on `npm`: + + ```json + "publish:nightly": "lerna publish from-package --dist-tag nightly --yes" + ``` + + The `skip_cleanup` flag tells Travis not to delete files not tracked by git, + such as the build directory of the packages: `dist`. + + This step runs only on the v11 of `Node` whenever there are new tags. + (see [`Releasing.md`](/docs-internal/Releasing.md)) + +## Useful readings + +- [lerna publish docs](https://github.com/lerna/lerna/tree/master/commands/publish) + (in particular the `from-package` positional and the `--dist-tag` and `--yes` flags) +- [lerna + travis setup demo](https://github.com/geut/lerna-travis-demo) +- [travis deployment docs](https://docs.travis-ci.com/user/deployment/) + +[travis-docs-env-vars]: https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings diff --git a/docs-internal/Continuous-integration.md b/docs-internal/Continuous-integration.md index 9a5573a66..46fef4886 100644 --- a/docs-internal/Continuous-integration.md +++ b/docs-internal/Continuous-integration.md @@ -1,9 +1,9 @@ # Continuous Integration -Having automated CI setup allows us to: +Having CI configured in an automated way, allows us to: -- reduce the feedback loop between the contributor and the reviewer - make the reviewing task less time-consuming and less prone to human errors +- reduce the feedback loop between the contributor and the reviewer ## Setup diff --git a/docs-internal/Releasing.md b/docs-internal/Releasing.md new file mode 100644 index 000000000..781e205fb --- /dev/null +++ b/docs-internal/Releasing.md @@ -0,0 +1,68 @@ +# Releasing + +Terminology for this context: + +- Releasing: marking (tagging) a new software version +- Publishing: uploading a new build to the package manager +- Deploying: same as publishing + +The act of making a new release is a manual step, as we need to assess whether we should bump a new +major, minor or patch. (see [semver docs](https://semver.org/)) + +## Preparing + +Before releasing let's make sure we are including the latest changes by updating the local branch: + +1. `git checkout master` +2. `git pull` +3. `git checkout release/v6.0.0` (the next tag of the `@aragon/cli` package) + +Prepare the release notes: + +1. Draft a new release on GitHub: +2. Summarize the changes since the last release: + +## Release all packages that have been updated + +1. Run `npm run version` and bump the versions according to the release summary. +2. On GitHub Releases, choose the project-wide tag (`@aragon/cli`'s version) and publish. +3. Wait for the CD agent to finish the automatic deployment. (see [`Continuous-deployment.md`](/docs-internal/Continuous-deployment.md)) +4. Make some noise on the `#dev` channel. + +## Distribution tags + +The tags we use are: `latest`, `stable`, `nightly`. + +> By default, `npm install ` (without any `@` or `@` specifier) installs the `latest` tag. +> +> By default, other than `latest`, no tag has any special significance to `npm` itself. + +To mark a `nightly` build as latest stable: + +```sh +npm dist-tag add @aragon/cli@6.0.0 stable +npm dist-tag add @aragon/cli@6.0.0 latest +``` + +## Something went wrong + +- Revert the last commit: + +```sh +git revert HEAD~ --hard +git push --force +``` + +- Delete the tags, locally and on the remote, i.e.: + +```sh +git tag --delete @aragon/cli@5.9.5 create-aragon-app@2.2.3 +git push --delete origin @aragon/cli@5.9.5 create-aragon-app@2.2.3 +``` + +Note: you cannot redeploy the same version to npm, a new version must be used. +(see [npm unpublish docs](https://docs.npmjs.com/cli/unpublish)) + +## Useful readings + +- [npm dist tag docs](https://docs.npmjs.com/cli/dist-tag) diff --git a/docs-internal/next/Specification.md b/docs-internal/next/Specification.md index d3e87e025..5036ad040 100644 --- a/docs-internal/next/Specification.md +++ b/docs-internal/next/Specification.md @@ -129,9 +129,9 @@ Data viz: ### Devchain API - `ensureConnection` -- `hasAragonDeployements` +- `hasAragonDeployments` - `deployAragon` -- `start` -- should save stdout and stderr in some files to be outputed by `aragon devchain output` +- `start` -- should save stdout and stderr in some files to be outputted by `aragon devchain output` ## Web3 `@aragon/web3-utils` diff --git a/lerna.json b/lerna.json index a2bb50ba7..36f9da420 100644 --- a/lerna.json +++ b/lerna.json @@ -2,5 +2,10 @@ "packages": [ "packages/*" ], - "version": "independent" + "version": "independent", + "command": { + "version": { + "allowBranch": ["release/*"] + } + } } diff --git a/package.json b/package.json index e29a1a9db..f194f5aed 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "test:e2e": "lerna run test --scope @aragon/e2e-tests", "test:coverage": "lerna run test:coverage:ci --ignore @aragon/e2e-tests", "report-coverage": "lcov-result-merger 'packages/*/coverage/lcov.info' | coveralls", - "publish": "lerna publish" + "release": "lerna version", + "publish:nightly": "lerna publish from-package --dist-tag nightly --yes" } } diff --git a/packages/aragon-cli/package.json b/packages/aragon-cli/package.json index e3e5692a6..1a9528f1d 100644 --- a/packages/aragon-cli/package.json +++ b/packages/aragon-cli/package.json @@ -21,7 +21,7 @@ "lint": "eslint src test/commands && documentation lint src", "test": "nyc ava", "test:watch": "ava --watch", - "test:coverage:ci": "nyc --all --reporter=lcovonly --exclude 'config/**' ava" + "test:coverage:ci": "nyc --all --reporter=lcovonly --exclude 'config/**' --exclude '**/*.test.js' ava" }, "repository": { "type": "git", diff --git a/packages/e2e-tests/src/cli/run.test.js.md b/packages/e2e-tests/src/cli/run.test.js.md index 07dbd512f..f41cc4b67 100644 --- a/packages/e2e-tests/src/cli/run.test.js.md +++ b/packages/e2e-tests/src/cli/run.test.js.md @@ -41,14 +41,14 @@ Generated by [AVA](https://ava.li). Prepare files for publishing [completed]␊ Generate application artifact [started]␊ Generate application artifact [completed]␊ - Publish foobarfoo.aragonpm.eth [started]␊ + Publish foobarfoo.open.aragonpm.eth [started]␊ Generating transaction [started]␊ - → Fetching DAO at 0x983b4Df4E8458D56CFDC51B9d2149381AF80308A...␊ + → Fetching DAO at 0x9a348D0c3f55c2B3f6A400CC1BE71c882Ff1bdC3...␊ Generating transaction [completed]␊ Sending transaction [started]␊ → Waiting for transaction to be mined...␊ Sending transaction [completed]␊ - Publish foobarfoo.aragonpm.eth [completed]␊ + Publish foobarfoo.open.aragonpm.eth [completed]␊ Fetch published repo [started]␊ Fetch published repo [completed]␊ Publish app to APM [completed]␊ @@ -88,7 +88,7 @@ Generated by [AVA](https://ava.li). i This is the configuration for your development deployment:␊ Ethereum Node: ws://localhost:8545␊ ENS registry: 0x5f6f7e8cc7346a11ca2def8f827b7a0b612c56a1␊ - APM registry: aragonpm.eth␊ + APM registry: open.aragonpm.eth␊ DAO address: 0xe5ac265B0FFE4b47C8386D7d715f3a3f6F8fb5B9␊ ␊ Opening http://localhost:3000/#/0xe5ac265B0FFE4b47C8386D7d715f3a3f6F8fb5B9 to view your DAO` diff --git a/packages/e2e-tests/src/cli/run.test.js.snap b/packages/e2e-tests/src/cli/run.test.js.snap index 24a116322faff4d83aee5436355a00904f044df4..0cb4bfa7748b5efe477a589858eb84ca026c639a 100644 GIT binary patch literal 1901 zcmV-z2a@MIVa@00000000A} zSKV$SNfq|af{=2tf*Y<2uU4}o61&^|Yhwoz$6;r+J2N69&}hU(b#=A7Hr-vVsGgUa^#1yffBo|7 z-@pCrr~moG-+uSG_wNsT`18p}&7ar){qy_1-iN*K*}V_G+xx+jAAWRUs4|3-LNZ#A zg~_?%tCCdQY^1s*Z#C}o^w$R$+!#?U$*KnFif;(Zsi;V%WJwBYxHjZO(WR`2u4t`u zY5q@TCd<0ujXK&v{VmRp`aRyh=*YB-gc?#yIB6XC0eNeLDL6`0%lA{b4d#)EbwuYm zXP4yptMiL)EUf;m#c%%jHMu#Z-D~|%NZ>f`o>IrbNt(7eGEs2dF?eU^0a%^oSF5BD zIw!QQiIL>w)t6m+bzNK|xHVT=K%$aWS(8so`ju4A-e0cc?u^%kye3RmMp4$y-yDPl z=BM4#kMG^J`E)KTc zcgQ^!pS?YRQ;KRA2SU?Saji)v)lKYoZr@j-)XTyX-*M)1_jD1tERIL#nVY0@Z!j1< z=%ULl5a!1r{E7-|0Yll9g0f6F!3?M9>s~|OHaH!5d-84WfE^*NvV-jY?RRiXmys05 zoMKpS8MTMtAc*?_l^D+F@M10!Wm$QH;0>bIPt#705ZxVmNf*6v;Dd*OE$i6C#}iXb~w zaswqp(`&2^EJSiGSIQO(OymaP02MxiS!*@4EctHsQpS*>HL4LtE3(oY?}5*GP;&Zn2z^a$+bw~$Y62< zHo3uLh|*pkKu7@TDY3@9Uh->e700tB-;do10UAkscjU9hspki7=mlpdjHjvVMq!jW zj-SSK6tj>oBJ!!ph2EZ*z*l=1aMz3z46;5X!jPP5Qc8$ajl8ds-Ssn|;~N|kLSq{E z$taE8ag;D8amPs#Qz!Nv&rNvb#$FJ_4s~1}In)oR>m@Wv-H?qF<_4j+JH*Hy0ui6JuSxwpnb8V1q@nZ0AJUHYZksEDE{78Z9ec z%1SU&=Zb1RIp9~&x=?C{vdaQ#R4GU%5C&O8?sHm}klvIp6^DRIEi9id!4xd7s*FO4 zwS>!UBCC}?I3VBr`7ahz%Gb@Uas%mrSaEaMl&&_s*1#W4@}MYFtWfw`E57D7wR*+% z1ZstlBk~JWZECeM_84Wba?>GXj`>cm$x>SKlcc?NYjR9pD+v_L;ifEcY0w&eo_(B77Fsm%nh{EgU)3&`41XrrJ|ovR=VvxvuxMV=p0*JX5+ z@+{8cQItf~NkVtT0@$$1IOBH8cgCxgvG<6ki_ks~C>w>rsdIk5@Do3p$6g$sMQP*) znMdJraUN$$a5_G)%3H?Gjj8wWdyeA_KOVlnJ?zB z(koG}%AE*Mq_R&G8URGL-V0EK3>C9JbcHf(1ziWu`@~$=fJl^d$%lHq{P9&;^hvIG zHtP?8{!wVaXf}p2a0ejptqj)H@{X}E^`kW5!2mZ~WA+vGxasWauz6~Bw7G`w81zFR z92lCvvFrE)!)BSoJEQA3pZw%zRl@Z?1L~WQT%;+lwmZL_4jWsTvEeplQ?%K-s-$L0 z)aJO=z-hQ8EnZ(%UFRTzQsuhr^9Z_}NaLjbLZ)BQ^H4*8ouYigA$I~G^Zx7a( n(TYKA;B&xX5G78+2488E+?kmU8<2q7mf(K@JHytW1rY!MOf$hd literal 1898 zcmV-w2bK6iRzV#=UrrAB41Zjwb*m85PM zHnIrv0nRR~d_uPQfgt;QLHrp(7P+@bwWxm0*lBdD#k!9=bsy&zonEi^PVaC3`uA_Y z{ln`|Kl$$;|NhNq-hbZh;m^p|>4#;veLg;s%gS&CU>@U9ZdWtLyHQ50_vpXTU1#TC^NK5|WRhB&l2=e8kk0G| z{x|476rUX#z$rzwjRT=+s<_r9lj=J5+il<0ptHyEQWPmh2igoyU!}XnqIgXeZ>tM^ z)J^%I#dhC^)$WQPR9_(&H3(-Dn7iV4x85D)oJpBb1)l?IDW)z5+~l`iA|i-PrNPl| z@UU3UxM3Fb>CtoSP3LkPdx?LV`SaKh;?p2JIXgWG+~aXNa{aLvyGLiS<2musU@*9M zi!QA|gdc|RJ1VRPjAB;{Dl*{&lbhmRcRKnWap|bqLvJz$oCwL39Z+|R-@qtc9#R}L zi4ncw)Z*u$h;l&54=#k+!TGCpZ2WM;+dyzIAs9PXuDx`)=Rvib1iLAgj{VN^J%Q*f zKd*Up!^QQCXvZZh1Tx4ygJeg^*2X>NH#S9$wSug1b;I=y>22*h;dd5^Ag|<-ASYCE z4JAX{OU*%_yv&hr6y#U} z->pSaV1IxxwXH+p8C;O2HMISH^7&H&@IhQ^bn$BIu>qCQl~lrXcCVFOi4=|uF4y3b z8$5<6?WF;f1W=t4E6nQ!zp`F&C|kUKKARtVe&B{)aC*den!0WjMw#RI zX-r2k3;8@EADUd~&3OrYwTFT2njwNg*84;ll2c7e36ZLi?KN_`egY(XjblP+Oang| zrLjAX66PfCI7wpa#J=OX36I>^3xe38j>{v5`T=#lgeIvQvT?%PAoR9}7}-OBp*v54 zEc1NE#=e(1viW{)PbNwjtBkDz7=!f3e zOWeTmlZ+)vK^>*A%&Vp{}jERsb#9n!Wru@Yoa$TikzS@BX< zf{{8`RP)Imzl7F>QZtlY6v&`TK{A0b$O>|w)3Sv0rhK6|1XOBasdNFZV0l?(6jH1u zTxkdQ|R1j)^ z!3`~`zL*fb7D(n`PDv`V45A5m+MCWkp)mddNVU;RAY`bF;2v)h`>fG^+}5k@JXUb3 ztXd^2##{90ZgXaiQ3q}7{r2qAPoQz&w@Em-6-~>+Jth;2rD}qLjcpqhV$Ta%+k4ga ziq%B)x_6(+luyW7PliK#N6w`-6TIj*YR}FgYYU-`fY1!-4P2wV2yFcZH>Ew$BOOkp=ls=%>&9tVQ}o6oz4Bkk4|DQ4o{;ra)ZpH zUKXCkSrQzN_pI@TY;$Ak9q69pIKvNyZ|@INw-PYNY|H@E^;_YOdXN6O`;PeMN7J95 zK0kT+>ct#(E{nsxDgJ}^wrVl!^QwOc;HEhc`JqKQEupCJWlBNy&iYG}9mM^vsG=pG z^>KUT%D%mkLXKwrwMb1qgA5AB59|YwS_N%Kivta3eb?-%d+T`T=8ty z9|H5E(ty!y3>DxGK;e5itgFQ>XJP6`X~Kg63R`FPo%FD2>glj~Y9!iR!FLS$K5z}p z%dhM@{=l4B*=uZg&7-eQZ_}O?N*i4Oo`eY zwiY-DH+;n_j3@bwuIRZ{!bPsxACS>?EA|io0GWfXi~s-t diff --git a/packages/e2e-tests/src/create-aragon-app/index.test.js b/packages/e2e-tests/src/create-aragon-app/index.test.js index b4c5ef90d..7214530ad 100644 --- a/packages/e2e-tests/src/create-aragon-app/index.test.js +++ b/packages/e2e-tests/src/create-aragon-app/index.test.js @@ -35,7 +35,7 @@ test('should create a new aragon app', async t => { t.falsy(await fs.pathExists(repoPath)) t.falsy(fs.pathExistsSync(licensePath)) t.is(undefined, packageJson.license) - t.is(`${name}.aragonpm.eth`, arapp.environments.default.appName) + t.is(`${name}.open.aragonpm.eth`, arapp.environments.default.appName) t.is(`${name}.open.aragonpm.eth`, arapp.environments.rinkeby.appName) t.is(`${name}.open.aragonpm.eth`, arapp.environments.mainnet.appName) })