Skip to content

Latest commit

 

History

History
299 lines (230 loc) · 11.7 KB

DEVELOPMENT.md

File metadata and controls

299 lines (230 loc) · 11.7 KB

Git workflow

Development on this project uses the GitHub Flow:

  1. Create your feature branch (git checkout -b my-new-feature)
  2. Stage your changes (git add)
  3. Commit your JSHint-compliant and test-passing changes (just run grunt) with a good commit message (git commit)
  4. Push to the branch (git push -u origin my-new-feature)
  5. Create a new Pull Request

NSIDC Continuous Integration

NSIDC's project CI utilizes internal configuration found in the .yaml, Vagrantfile and /puppet/. If you are utilizing this project external to NSIDC you can safely ignore those files and the remainder of this section.

Most projects just have a file called vagrant-nsidc.yaml, which specifies a project name for the plugin to use. This repository really has two projects, ade_search and nsidc_search, configured in vagrant-nsidc.ade_search.yaml and vagrant-nsidc.nsidc_search.yaml.

To use the correct config file, set the appropriate environment variable:

export VAGRANT_NSIDC_YAML=vagrant-nsidc.ade_search.yaml

If switching which project you are working on, take care that you are using the correct config file, and that the temp file .nsidc-project.yaml references the right project.

Once that is setup, machines can be provisied as expected using the vagrant-nsidc plugin.

Grunt

Run grunt tasks to get a list and descriptions of the most important grunt tasks defined in Gruntfile.js. Tasks that should use additional command line flags list those flags at the end of the description.

The default grunt task (i.e., just running grunt) runs syntax checkers and unit tests.

grunt tasks does not list grunt watch tasks, and there are a couple of those that are useful:

  • grunt watch:lint-test will automatically run JSHint, scss-lint, and the Jasmine test suite whenever a JavaScript or Sass file is changed
  • grunt watch:build-$PROJECT automatically runs grunt build:$PROJECT-dev whenever a Sass or Jade file is changed (PROJECT must be acadis or nsidc)

Build

grunt build:nsidc and grunt build:acadis will create a build/ directory containing HTML and CSS files generated from Jade and Sass files, as well as a minified JavaScript file created by the RequireJS Optimizer. Other files, such as external JavaScript libs and image files, are also copied to build/ so that it contains everything needed to run the interface in a browser. This directory can then be compressed and used for deployment.

grunt build:nsidc-dev and grunt build:acadis-dev skip the RequireJS optimizer step, and do not create a build/ directory. Instead, the generated HTML and CSS are kept within src/.

The environment defaults to development, to set the environment pass an environment argument to grunt, for example grunt build:nsidc --environment=production. The CSS generated from the Sass source varies based on the environment; for production, it will be compressed, otherwise it is more readable and includes line numbers mapping to the original source files. The generated HTML also uses the environment to load the appropriate configuration from src/conf/.

Running the app locally

Run grunt build:nsidc-dev or grunt build:acadis-dev to generate the appropriate src/index.html file (as well as css files), then ./run_local_webserver.rb and open your browser to http://localhost:8081.

To run using the code generated by the RequireJS optimizer (concatenated and minified js, rather than the standard source), modify local_webserver_config.yaml to use build/ instead of src/.

Running the app through nginx

In order for the ADE interface to not run into cross browser scripting issues connecting to the BCube GI-Cat/GI-Axe instances, the nginx conf files must be changed. Theoretically these changes can be included in the Puppet file and automatically deployed but I don't have time to figure out exactly how to do that. Therefore to create proxies you must logon to the VM and add the following to /etc/nginx/nginx.conf: upstream bcube-server { server bcube.geodab.eu; }

upstream bcube-axe-server { server bcubeaxe.geodab.eu; }

and the following to /etc/nginx/sites-enabled/search.conf: location /gi-cat { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-NginX-Proxy true; proxy_pass http://bcube-server/bcube-broker/; }

location /gi-axe { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-NginX-Proxy true; proxy_pass http://bcube-axe-server/bcube-broker-axe/; }

Then nginx must be restarted: sudo service nginx restart

External services

The external services used by the search portal are defined in local_webserver_config.yaml. search_proxies are the default choice, and contain endpoints for the services running on localhost. integration_proxies and qa_proxies are also defined.

To run against services on integration:

./run_local_webserver.rb 8081 integration_proxies

To run against services on qa:

./run_local_webserver.rb 8081 qa_proxies

Running the acceptance tests locally

Prerequisites

  • Firefox
  • If using the development VM under Mac OS X, XQuartz is required.

To run the acceptance tests on your machine from the development VM, you will first need to ssh with X windowing enabled. Instead of connecting with vagrant ssh, use ssh -X [email protected] -p 2222.

grunt test:acceptance --project=ade_search --environment=integration

project can be ade_search or nsidc_search

environment can be integration, qa, or staging.

The URL used by Cucumber is built from project and environment. To test against a different URL (like when running the tests locally), specify with a --url flag (project must still be specified):

grunt test:acceptance --url=http://localhost:8081 --project=ade_search

CSS / Sass

  • The structure of our Sass code is as follows:
    • src/sass
      • _config_*.scss
        • contains different variable definitions to separate styles across projects built from the common codebase
      • *_main.scss
        • imports the configuration and modules for that project
      • modules/
        • a Sass module defines the styling for a specific part of the page; keeping our code more modular makes it easier to identify places where it can be shared across projects, and makes it easier to find a particular selector you are interested in modifying or investigating
      • utilities/
        • our own custom Sass functions; no CSS rules are defined in here
      • junk/
        • old, monolithic CSS files converted to Sass syntax still needing cleanup (break into smaller parts, put those parts in modules/)
  • grunt sass:dev generates src/css/acadis-search.css and src/css/nsidc-search.css, combining the project-specifc scss and the common files into one
  • grunt sass:$PROJECT generates tmp/css/$PROJECT-search.css; this is used by grunt build:$PROJECT (see the Build section)
  • grunt sass is configured to compress the generated CSS files and generate source maps, allowing tools like the Chrome Inspector to automatically show line numbers from the original Sass files
  • grunt scsslint runs the scss-lint tool on the Sass files. It is configured by rules in config/scss-lint.yml (with additional rules that should be cleaned up in config/scsslint-todo.yml)
  • Compass is used to handle cross-browser CSS3 features with less code in the files we write.
  • Using Sass requires some gems which can be installed with bundle install.

Unit tests

Run the unit tests in PhantomJS with grunt jasmine. Test code is located in spec/, written in Jasmine 1.3 along with Sinon.

It can helpful for debugging purposes to run the unit tests in a browser. To do so, follow these steps:

  • if you don't already have the file _SpecRunner.html, run grunt test:unit to generate the file
  • make sure your port 8081 is open (kill the local webserver if you are running it)
  • grunt serve-tests
  • point your browser to localhost:8081/_SpecRunner.html

JSHint

Run with grunt jshint. Run automatically whenever a JavaScript file is changed with grunt watch:jshint.

JSHint is configured in .jshintrc, a JSON file containing a list of options and allowed global variables.

RuboCop

The acceptance tests use the official Ruby implementation of Cucumber, and we use the tool RuboCop to lint the Ruby code contained within this project. After installing the gems listed in Gemfile with bundle install, RuboCop can be run with bundle exec rubocop. Settings can be found in .rubocop.yml.

Git Hooks

Our build server attempts to build the project with every revision, and it requires that linters and unit tests pass successfully. To protect yourself from the embarrasment of breaking the build, git hooks can be set up to run everything on your local box before you push.

Git hooks are configured in Gruntfile.js with the grunt-githooks plugin. Running grunt githooks udpates files in your .git/hooks/ so that the specific grunt tasks will be run at the given git events. This means if the githooks task configuration is ever changed, you will need to run grunt githooks again to update your hook scripts (and if a hook is removed the Gruntfile configuration, you may need to delete the old script from .git/hooks/).

Currently included hooks (and the tasks they run) are:

  • pre-commit: scsslint and jshint
  • pre-push: jasmine

Bootstrap

We are using a customized version of Bootstrap to avoid conflicts with global NSIDC styles included via SSI. To add to the existing set of styles and scripts go to Bootstrap's customize page.

To generate the download, first deselect all items in the "Choose components" and "Select jQuery plugins" sections.

In "Choose components" select the following:

  • Base CSS
    • Buttons
  • Componets
    • Button groups and dropdowns
    • Alerts
  • JS Components
    • Dropdowns

In "Select jQuery plugins" select the following:

  • Dropdowns
  • Buttons

Replace the src/contrib/bootstrap/ directory with the contents of the downloaded zip file. Be sure to update this list of components after each new download.

Releases/Changelog

The version in package.json is updated automatically with the grunt release:$part task (where $part is patch, minor, or major). This task creates a git tag for the new version, and adds 2 new header lines to CHANGELOG.md, indicating the version number and the date it was released. Therefore, new changes should be documented at the top of CHANGELOG.md without a version header, since it will be added automatically later.