{"_id":"59365227e16643001bac5046","category":{"_id":"59365227e16643001bac5033","version":"59365226e16643001bac5030","project":"543026235eceb608003fde5f","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-06-05T13:44:53.935Z","from_sync":false,"order":2,"slug":"contributing","title":"Contributing"},"project":"543026235eceb608003fde5f","user":"565743e4c19631170079793c","parentDoc":null,"version":{"_id":"59365226e16643001bac5030","project":"543026235eceb608003fde5f","__v":1,"createdAt":"2017-06-06T06:56:38.999Z","releaseDate":"2017-06-06T06:56:38.999Z","categories":["59365227e16643001bac5031","59365227e16643001bac5032","59365227e16643001bac5033","59365227e16643001bac5034"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0.0"},"__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-06-05T14:05:48.205Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":3,"body":"This guide is about day-to-day development of [Ghost-Admin](https://github.com/TryGhost/Ghost-Admin) (our ember.js admin client) that can be found in your local Ghost install at `core/client` after following the normal [Ghost developer install guide](doc:working-with-ghost) \n\n\n[block:api-header]\n{\n  \"title\": \"Pre-requisites\"\n}\n[/block]\nFor ember.js development we have one primary pre-requisite and that is [ember-cli](https://ember-cli.com/user-guide/) which should have been installed globally by the [`yarn run init`](doc:working-with-ghost#initial-setup) command.\n\nEven if you already have these installed it's worth running these commands again as it will update them to the latest version.\n\n1. `yarn global add ember-cli` - makes the `ember` command available\n2. `yarn global add bower` - another dependency manager, makes the `bower` command available\n\n### Watchman\n\n`ember-cli` will make use of `watchman` if it's available, this dependency isn't strictly necessary but it does speed things up and helps ensure that file changes are picked up reliably.\n\n[Check the ember-cli watchman docs](https://ember-cli.com/user-guide/#watchman) for more info and an installation guide.\n[block:api-header]\n{\n  \"title\": \"Git Setup\"\n}\n[/block]\nWe use git submodules to manage Ghost's sub-projects such as Ghost-Admin and Casper. The [`npm run init` command](doc:working-with-ghost#initial-setup) that is run as part of the Ghost installation will set this up for you but there are a few things that make it slightly different to the typical single-project git workflow...\n\n1. Treat `core/client` as if it is a clone of the Ghost-Admin repository, it will (mostly) behave as though it's a separate git repository\n2. After the initial Ghost installation you will want to configure your `core/client` repo so that you can make PRs and do all that fun git stuff\n    1. Ensure you have forked [Ghost-Admin](https://github.com/TryGhost/Ghost-Admin) and you know your fork's git location (eg. `git:::at:::github.com:<username>/Ghost-Admin.git`)\n    2. `cd core/client`\n    3. `git remote rename origin upstream`\n    4. `git remote set-url upstream git@github.com:TryGhost/Ghost-Admin.git`\n    5. `git remote add origin git@github.com:<username>/Ghost-Admin.git`\n    6. `git remote --verbose` should now output something like this:\n\n        ```\n        origin    git@github.com:<username>/Ghost-Admin.git (fetch)\n        origin    git@github.com:<username>/Ghost-Admin.git (push)\n        upstream  git@github.com:TryGhost/Ghost-Admin.git (fetch)\n        upstream  git@github.com:TryGhost/Ghost-Admin.git (push)\n        ```\n3. You can now use any git command inside `core/client` as normal. Pushes to `origin` will go to your fork from where you can open PRs\n4. Run `git checkout master && git pull upstream master` to switch to the `master` branch and update it\n5. If you ever need to edit the git config for `core/client` it's _not_ where you might expect at `ghost/core/client/.git/config` but instead located higher up in the directory tree at `ghost/.git/modules/core/client/config`\n\n\n[block:api-header]\n{\n  \"title\": \"Day-to-day Development\"\n}\n[/block]\n## Getting up to date with master\n\nMost of the time when you're getting started with development for the day you'll want to ensure that you're working on top of the latest client code. The typical workflow for this is to switch to the `master` branch and pull in changes before making sure you have the latest dependencies installed...\n\n1. `git checkout master`\n2. `git pull upstream master`\n3. `npm install`\n4. `bower install`\n\nIf you were working on a feature branch you'll probably want to rebase it now so that you're working on top of the latest code rather than staying at the point in time you originally created your branch:\n\n1. `git checkout <feature-branch>`\n2. `git rebase master`\n\n<sub>_**Note:** you really do want to use `rebase` and not `merge`!_</sub>\n<sub>_**yarn.lock conflicts?** check the [yarn.lock conflict resolution guide](#yarnlock-conflicts)_</sub>\n\n## Making client changes\n\nMaking changes to the client isn't too dissimilar to making changes to Ghost itself, it helps to have multiple terminal tabs open so that you can run `grunt dev` in one and continue to use `git` or other commands in the other.\n\nIn the first tab:\n1. Ensure you're in the root of your ghost directory\n2. Run `grunt dev` - this starts Ghost in development mode and also starts `ember-cli` watching the client files to rebuild any time a client file is changed\n3. Wait until you see something like `Build successful - 18858ms.` in the output - if it's been a while since you last ran `grunt dev` this might take some time, possibly 1min+ on a completely fresh install\n4. Open the admin area in a browser, this will typically be at http://localhost:2368/ghost/\n\nYou can now edit any `core/client/*` files in your editor of choice, any change to a file will kick off an automatic rebuild, if you're watching the `grunt dev` output you will see something like this:\n\n```\nfile changed components/gh-publishmenu-draft.js\n\nBuild successful - 2468ms.\n\nSlowest Nodes (totalTime => 5% )              | Total (avg)         \n----------------------------------------------+---------------------\nAssetRewrite (1)                              | 1248ms              \nPostcssCompiler (2)                           | 171ms (85 ms)       \nFingerprint (1)                               | 152ms               \nSourceMapConcat: Concat: Vendor /asset... (1) | 128ms \n```\n\nThis will work for nearly every js/hbs/css/asset file, even changes to files in `node_modules` will be picked up which is useful when debugging addons. After the rebuild's finished you will need to manually refresh the browser to see changes but this should soon be automatic.\n\nYou can typically leave `grunt dev` running for as long as you are working - if you experience issues with it crashing *please* mention it on [slack](https://slack.ghost.org) or [raise an issue](https://github.com/TryGhost/Ghost/issues/new) including the error log and anything you can remember doing when it died.\n\nTo stop the development server press <kbd>Ctrl-C</kbd> _once_ in the tab where `grunt dev` is running, it will sometimes take a second or two to shut down whilst `ember-cli` does some cleanup in the background.\n\nThere is one file that won't rebuild and will need `grunt dev` to be stopped and restarted:\n\n- `ember-cli-build.js` - this is what configures the `ember-cli` build pipeline, it's not edited regularly but if it is you'll need to hit <kbd>Ctrl-C</kbd> in your `grunt dev` tab then run `grunt dev` again.\n\n## Managing dependencies\n\nWe have a `yarn.lock` file in the repository that is used on Travis for CI tests and by core team members. As such if you are adding/removing/changing dependencies you *always* need to use the corresponding `yarn` commands to ensure that the lockfile is updated and Travis/team mates will have the correct dependencies installed.\n\n- Adding dependencies: `yarn add some-package -D` (all Ghost-Admin deps will be `devDependencies`)\n- Removing dependencies: `yarn remove some-package`\n  - Note that removing the package from `package.json` manually then running `yarn install` will *not* fully remove the dependency from `yarn.lock`\n- Updating dependencies: `yarn add some-package -D --exact`\n\n### yarn.lock conflicts\n\nWhen rebasing a feature branch it's possible you'll get conflicts on `yarn.lock` because there were dependency changes in both `master` and `<feature-branch>`. I find the best way to resolve these is to work through the following:\n\n1. Note what dependencies have changed in `package.json` (for this example say dev dep `dev-1` was added and dev dep `dev-2` was removed)\n2. `git reset HEAD package.json yarn.lock` - unstage the files\n3. `git checkout -- package.json yarn.lock` - remove local changes\n4. `yarn add dev-1 -D` - re-adds the dependency and updates yarn.lock\n5. `yarn remove dev-2` - removes the dependency and updates yarn.lock\n6. `git add package.json yarn.lock` - re-stage the changes\n7. `git rebase --continue` - continue with the rebase\n\nThat ensures that we're not introducing weird edge cases because we let `yarn` auto-generate the lockfile rather than trying to manually merge potentially incompatible changes.\n\n\n[block:api-header]\n{\n  \"title\": \"Testing\"\n}\n[/block]\nAny time you have `grunt dev` running the client tests will be available at http://localhost:4200/tests\n\nWhen loading the tests url all of the tests will run in your current browser and the tests will re-run any time a client file is changed.\n\nYou can click on the test group title links to run only certain tests or use the individual `>` links to run a single test. You can also modify the `?grep=...` query param to limit tests in the same way as the `ember test -f '...'` command mentioned below.\n\n## Testing Tips\n\nOpening the web inspector and following the Console tab whilst the tests are running can be useful - sometimes you will get a more useful error there than is shown in the web interface, or if you have added `console.log` statements they can help highlight the test behaviour you're working on.\n\nIt can be helpful to [enable Mirage logs](https://github.com/TryGhost/Ghost-Admin/blob/master/mirage/config.js#L39) whilst testing, this will output every handled request and the return value in the web inspector console tab - this is very useful as there won't be anything in the Network tab during tests because every request is mocked and handled by [ember-cli-mirage](http://www.ember-cli-mirage.com).\n\nWhen working on acceptance tests it's possible to pause the tests running in the browser so that you can visually inspect the screen and use the normal web inspector `Inspect element` and console techniques for examining the current app state. To initiate the pause, find the point in the acceptance test that you want to stop and add the following lines:\n\n```\nthis.timeout(0);\nreturn pauseTest();\n```\n\nIf you are running tests from the CLI and pass the `--server` argument you are free to use the web interface in the opened browsers to limit the tests which are being run in the same way as mentioned above when using http://localhost:4200/tests\n\n## CLI Commands\n\nClient tests are always run by initiating a variation of `ember test ...` inside the `core/client` directory. The available params in order of usefulness from low to high...\n\n- `ember test` - this is what Travis runs, it will run all of the tests in Chrome/Firefox sequentially then exit. There will be a _lot_ of log output in the console and the browsers won't stay open for you to view what tests have/haven't passed so it's not particularly useful for local development\n- `ember test --server` (or `-s`) - similar to `ember test` in that it will run all tests but it differs significantly in that Chrome and Firefox will run in parallel and will not quit once the tests finish but instead stay open waiting for file changes which will trigger the tests to re-run\n- `ember test -f 'gh-my-component'` - will only run tests where the `describe()` or `it()` text matches the supplied argument - watch out, it's case-sensitive!\n- `ember test --launch=chrome` - will only open Chrome rather than Chrome+Firefox, useful to keep system resources under control \n- `ember test -s -f 'Acceptance: Settings - General' --launch=chrome` - the typical test command to use when doing local development, it will only run the tests you're interested in to keep the test cycle fast, it will re-run on any file changes, and it only opens Chrome so you don't have two automated browsers bringing your laptop to it's knees.\n\n## Troubleshooting\n\n### ENOENT: no such file or directory, stat 'core/built/assets/img/favicon.ico' at Error (native)\n\nYour admin client was not build yet. Please run `grunt prod` for production or `grunt dev`.\n\n### Admin not loading with `TypeError: Cannot read property 'tagName' of undefined`\n\nIf you are using `ember test` commands you will **not** be able to use `grunt dev` at the same time - `ember test` will generate test-specific files that will result in a blank screen and the above error message in the web inspector console when you try to access your admin area. After running `ember test` you will need to start `grunt dev` or `grunt build` and wait for the \"Build successful\" line before the admin is usable again.","excerpt":"","slug":"working-with-the-admin-client","type":"basic","title":"Working with the admin client"}

Working with the admin client


This guide is about day-to-day development of [Ghost-Admin](https://github.com/TryGhost/Ghost-Admin) (our ember.js admin client) that can be found in your local Ghost install at `core/client` after following the normal [Ghost developer install guide](doc:working-with-ghost) [block:api-header] { "title": "Pre-requisites" } [/block] For ember.js development we have one primary pre-requisite and that is [ember-cli](https://ember-cli.com/user-guide/) which should have been installed globally by the [`yarn run init`](doc:working-with-ghost#initial-setup) command. Even if you already have these installed it's worth running these commands again as it will update them to the latest version. 1. `yarn global add ember-cli` - makes the `ember` command available 2. `yarn global add bower` - another dependency manager, makes the `bower` command available ### Watchman `ember-cli` will make use of `watchman` if it's available, this dependency isn't strictly necessary but it does speed things up and helps ensure that file changes are picked up reliably. [Check the ember-cli watchman docs](https://ember-cli.com/user-guide/#watchman) for more info and an installation guide. [block:api-header] { "title": "Git Setup" } [/block] We use git submodules to manage Ghost's sub-projects such as Ghost-Admin and Casper. The [`npm run init` command](doc:working-with-ghost#initial-setup) that is run as part of the Ghost installation will set this up for you but there are a few things that make it slightly different to the typical single-project git workflow... 1. Treat `core/client` as if it is a clone of the Ghost-Admin repository, it will (mostly) behave as though it's a separate git repository 2. After the initial Ghost installation you will want to configure your `core/client` repo so that you can make PRs and do all that fun git stuff 1. Ensure you have forked [Ghost-Admin](https://github.com/TryGhost/Ghost-Admin) and you know your fork's git location (eg. `git@github.com:<username>/Ghost-Admin.git`) 2. `cd core/client` 3. `git remote rename origin upstream` 4. `git remote set-url upstream git@github.com:TryGhost/Ghost-Admin.git` 5. `git remote add origin git@github.com:<username>/Ghost-Admin.git` 6. `git remote --verbose` should now output something like this: ``` origin git@github.com:<username>/Ghost-Admin.git (fetch) origin git@github.com:<username>/Ghost-Admin.git (push) upstream git@github.com:TryGhost/Ghost-Admin.git (fetch) upstream git@github.com:TryGhost/Ghost-Admin.git (push) ``` 3. You can now use any git command inside `core/client` as normal. Pushes to `origin` will go to your fork from where you can open PRs 4. Run `git checkout master && git pull upstream master` to switch to the `master` branch and update it 5. If you ever need to edit the git config for `core/client` it's _not_ where you might expect at `ghost/core/client/.git/config` but instead located higher up in the directory tree at `ghost/.git/modules/core/client/config` [block:api-header] { "title": "Day-to-day Development" } [/block] ## Getting up to date with master Most of the time when you're getting started with development for the day you'll want to ensure that you're working on top of the latest client code. The typical workflow for this is to switch to the `master` branch and pull in changes before making sure you have the latest dependencies installed... 1. `git checkout master` 2. `git pull upstream master` 3. `npm install` 4. `bower install` If you were working on a feature branch you'll probably want to rebase it now so that you're working on top of the latest code rather than staying at the point in time you originally created your branch: 1. `git checkout <feature-branch>` 2. `git rebase master` <sub>_**Note:** you really do want to use `rebase` and not `merge`!_</sub> <sub>_**yarn.lock conflicts?** check the [yarn.lock conflict resolution guide](#yarnlock-conflicts)_</sub> ## Making client changes Making changes to the client isn't too dissimilar to making changes to Ghost itself, it helps to have multiple terminal tabs open so that you can run `grunt dev` in one and continue to use `git` or other commands in the other. In the first tab: 1. Ensure you're in the root of your ghost directory 2. Run `grunt dev` - this starts Ghost in development mode and also starts `ember-cli` watching the client files to rebuild any time a client file is changed 3. Wait until you see something like `Build successful - 18858ms.` in the output - if it's been a while since you last ran `grunt dev` this might take some time, possibly 1min+ on a completely fresh install 4. Open the admin area in a browser, this will typically be at http://localhost:2368/ghost/ You can now edit any `core/client/*` files in your editor of choice, any change to a file will kick off an automatic rebuild, if you're watching the `grunt dev` output you will see something like this: ``` file changed components/gh-publishmenu-draft.js Build successful - 2468ms. Slowest Nodes (totalTime => 5% ) | Total (avg) ----------------------------------------------+--------------------- AssetRewrite (1) | 1248ms PostcssCompiler (2) | 171ms (85 ms) Fingerprint (1) | 152ms SourceMapConcat: Concat: Vendor /asset... (1) | 128ms ``` This will work for nearly every js/hbs/css/asset file, even changes to files in `node_modules` will be picked up which is useful when debugging addons. After the rebuild's finished you will need to manually refresh the browser to see changes but this should soon be automatic. You can typically leave `grunt dev` running for as long as you are working - if you experience issues with it crashing *please* mention it on [slack](https://slack.ghost.org) or [raise an issue](https://github.com/TryGhost/Ghost/issues/new) including the error log and anything you can remember doing when it died. To stop the development server press <kbd>Ctrl-C</kbd> _once_ in the tab where `grunt dev` is running, it will sometimes take a second or two to shut down whilst `ember-cli` does some cleanup in the background. There is one file that won't rebuild and will need `grunt dev` to be stopped and restarted: - `ember-cli-build.js` - this is what configures the `ember-cli` build pipeline, it's not edited regularly but if it is you'll need to hit <kbd>Ctrl-C</kbd> in your `grunt dev` tab then run `grunt dev` again. ## Managing dependencies We have a `yarn.lock` file in the repository that is used on Travis for CI tests and by core team members. As such if you are adding/removing/changing dependencies you *always* need to use the corresponding `yarn` commands to ensure that the lockfile is updated and Travis/team mates will have the correct dependencies installed. - Adding dependencies: `yarn add some-package -D` (all Ghost-Admin deps will be `devDependencies`) - Removing dependencies: `yarn remove some-package` - Note that removing the package from `package.json` manually then running `yarn install` will *not* fully remove the dependency from `yarn.lock` - Updating dependencies: `yarn add some-package -D --exact` ### yarn.lock conflicts When rebasing a feature branch it's possible you'll get conflicts on `yarn.lock` because there were dependency changes in both `master` and `<feature-branch>`. I find the best way to resolve these is to work through the following: 1. Note what dependencies have changed in `package.json` (for this example say dev dep `dev-1` was added and dev dep `dev-2` was removed) 2. `git reset HEAD package.json yarn.lock` - unstage the files 3. `git checkout -- package.json yarn.lock` - remove local changes 4. `yarn add dev-1 -D` - re-adds the dependency and updates yarn.lock 5. `yarn remove dev-2` - removes the dependency and updates yarn.lock 6. `git add package.json yarn.lock` - re-stage the changes 7. `git rebase --continue` - continue with the rebase That ensures that we're not introducing weird edge cases because we let `yarn` auto-generate the lockfile rather than trying to manually merge potentially incompatible changes. [block:api-header] { "title": "Testing" } [/block] Any time you have `grunt dev` running the client tests will be available at http://localhost:4200/tests When loading the tests url all of the tests will run in your current browser and the tests will re-run any time a client file is changed. You can click on the test group title links to run only certain tests or use the individual `>` links to run a single test. You can also modify the `?grep=...` query param to limit tests in the same way as the `ember test -f '...'` command mentioned below. ## Testing Tips Opening the web inspector and following the Console tab whilst the tests are running can be useful - sometimes you will get a more useful error there than is shown in the web interface, or if you have added `console.log` statements they can help highlight the test behaviour you're working on. It can be helpful to [enable Mirage logs](https://github.com/TryGhost/Ghost-Admin/blob/master/mirage/config.js#L39) whilst testing, this will output every handled request and the return value in the web inspector console tab - this is very useful as there won't be anything in the Network tab during tests because every request is mocked and handled by [ember-cli-mirage](http://www.ember-cli-mirage.com). When working on acceptance tests it's possible to pause the tests running in the browser so that you can visually inspect the screen and use the normal web inspector `Inspect element` and console techniques for examining the current app state. To initiate the pause, find the point in the acceptance test that you want to stop and add the following lines: ``` this.timeout(0); return pauseTest(); ``` If you are running tests from the CLI and pass the `--server` argument you are free to use the web interface in the opened browsers to limit the tests which are being run in the same way as mentioned above when using http://localhost:4200/tests ## CLI Commands Client tests are always run by initiating a variation of `ember test ...` inside the `core/client` directory. The available params in order of usefulness from low to high... - `ember test` - this is what Travis runs, it will run all of the tests in Chrome/Firefox sequentially then exit. There will be a _lot_ of log output in the console and the browsers won't stay open for you to view what tests have/haven't passed so it's not particularly useful for local development - `ember test --server` (or `-s`) - similar to `ember test` in that it will run all tests but it differs significantly in that Chrome and Firefox will run in parallel and will not quit once the tests finish but instead stay open waiting for file changes which will trigger the tests to re-run - `ember test -f 'gh-my-component'` - will only run tests where the `describe()` or `it()` text matches the supplied argument - watch out, it's case-sensitive! - `ember test --launch=chrome` - will only open Chrome rather than Chrome+Firefox, useful to keep system resources under control - `ember test -s -f 'Acceptance: Settings - General' --launch=chrome` - the typical test command to use when doing local development, it will only run the tests you're interested in to keep the test cycle fast, it will re-run on any file changes, and it only opens Chrome so you don't have two automated browsers bringing your laptop to it's knees. ## Troubleshooting ### ENOENT: no such file or directory, stat 'core/built/assets/img/favicon.ico' at Error (native) Your admin client was not build yet. Please run `grunt prod` for production or `grunt dev`. ### Admin not loading with `TypeError: Cannot read property 'tagName' of undefined` If you are using `ember test` commands you will **not** be able to use `grunt dev` at the same time - `ember test` will generate test-specific files that will result in a blank screen and the above error message in the web inspector console when you try to access your admin area. After running `ember test` you will need to start `grunt dev` or `grunt build` and wait for the "Build successful" line before the admin is usable again.