The Human Layer of the Stack
## Introduction and Contribution Guideline Welcome to the [dev.to](https://dev.to) codebase. We are so excited to have you. Most importantly, all contributors must abide by the [code of conduct](https://dev.to/code-of-conduct). With your help, we can build out the DEV Community platform to be more stable and better serve the community. We are a [Ruby on Rails](http://rubyonrails.org/). When in doubt, try to do things "The Rails Way", but it is an evolving codebase and we will learn from all new contributions in order to evolve. ### How to contribute When in doubt, ask! This is a new process and we need to learn from pain points. **Refactoring** code, e.g. improving the code without modifying the behavior is an area that can probably be done based on intuition and may not require much communication to be merged. **Fixing bugs** may also not require a lot of communication, but the more the better. Please surround bug fixes with ample tests. Bugs are magnets for other bugs. Write tests near bugs! **Building features** is the area which will require the most communication and/or negotiation. Every feature is subjective and open for debate. Let's talk about the features! ### Clean code with tests Even though some of the existing code is poorly written or untested, we must have more scrutiny for code going forward. We test with [rspec](http://rspec.info/), let us know if you have any questions about this! ### The bottom line We are all humans trying to work together to improve things for the community. Always be kind and appreciate the need for tradeoffs. ❤️ # Getting Started #### Prerequisite - Ruby: we recommend using [rbenv](https://github.com/rbenv/rbenv) to install the Ruby version listed on the badge. - Bundler: `gem install bundler` - Foreman: `gem install foreman` - Yarn: use `brew install yarn` to install yarn. It will also install node if you don't already have it. - PostgresSQL: the easiest way to get started with this is to use [Postgres.app](https://postgresapp.com/). #### Installation steps 1. `git clone git@github.com:thepracticaldev/dev.to_core.git` 2. `bundle install` 3. `bin/yarn` 4. Set up your environment variables/secrets - Create a `config/application.yml` file to store development secrets. This is a personal file that is ignored in git. - Copy [`config/sample_application.yml`](config/sample_application.yml) in order to create a valid `application.yml` - You'll need to get your own free API keys for a few services in order to get your development environment running. [**Follow this wiki to get them.**](https://github.com/thepracticaldev/dev.to_core/wiki/Getting-API-Keys-for-Basic-Development) - If you are missing `ENV` variables on bootup, `_env_checker.rb` will let you know. If you add or remove `ENV` vars to the project, you must also modify this file before they can be merged. The wiki above should handle all the necessary keys for basic development. - You do not need "real" keys for basic development. Some features require certain keys, so you may be able to add them as you go. 5. Run `bin/setup` #### Starting the application We're mostly a Rails app, with a bit of Webpack sprinkled in. **For most cases, simply running `bin/rails server` will do.** If you're working with Webpack though, you'll need to run the following: - Run __`bin/startup`__ to start the server, Webpack, and our job runner `delayed_job`. `bin/startup` runs `foreman start -f Procfile.dev` under the hood. - `alias start="bin/startup"` makes this even faster. 😊 - If you're using __`pry`__ for debugging in Rails, note that using `foreman` and `pry` together works, but it's not as clean as `bin/rails server`. Here are some singleton commands you may need, usually in a separate instance/tab of your shell. - Running the job server (if using `bin/rails server`) -- this is for mostly for notifications and emails: __`bin/rails jobs:work`__ - Clearing jobs (in case you don't want to wait for the backlog of jobs): __`bin/rails jobs:clear`__ Current gotchas: potential environment issues with external services need to be worked out. ## 🔑 Key App tech/services - We use **Puma** for the server - We [rely heavily on edge caching](https://dev.to/ben/making-devto-insanely-fast) with **Fastly** - We use **Cloudinary** for image manipulation/serving - We use **Keen** for event storage - We use **Airbrake** for error monitoring - We use **Timber** for logging - We use **Delayed Job** for background workers - We use **Algolia** for search - We use **Redcarpet/Rouge** for Markdown - We use **Carrierwave/Fog/AWS S3** for image upload/storage - We use a modified version of **InstantClick** instead of **Turbolinks** - We are hosted on **Heroku** - We use **Heroku scheduler** for scheduled jobs (default) - We use **Sendgrid** for API-triggered mailing - We use **Mailchimp** for marketing/outreach emails - We use **Figaro** for app configuration. - We use **CounterCulture** to keep track of association counts (counter caches) - We use **Rolify** for role management. - We use **Pundit** for authorization. - We use Service Workers to proxy traffic There's more, but that's a decent overview of the key need-to-knows. ## Workflow Suggestion We use [Spring](https://github.com/rails/spring) and it is already included in the project. 1. Use the provided bin stubs to automatically start Spring, i.e. `bin/rails server`, `bin/rspec spec/models/`, `bin/rake db:migrate`. 2. If Spring isn't picking up on new changes, use `spring stop`. For example, Spring should always be restarted if there's a change in environment key. 3. Check Spring's status whenever with `spring status`. Caveat: `bin/rspec` is not equipped with Spring because it affect Simplecov's result. Instead use `bin/spring rspec`. ## Style Guide This project follows [Bbatsov's Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide), using [Rubocop](https://github.com/bbatsov/rubocop) along with [Rubocop-Rspec](https://github.com/backus/rubocop-rspec) as the code analyzer. If you have Rubocop installed with your text editor of choice, you should be up and running. Settings can be edited in `.rubocop.yml`. For Javascript, we follow [Airbnb's JS Style Guide](https://github.com/airbnb/javascript), using [ESLint](https://eslint.org/) and [prettier](https://github.com/prettier/prettier). If you have ESLint installed with your text editor of choice, you should be up and running. When commits are made, a git precommit hook runs via [husky](https://github.com/typicode/husky) and [lint-staged](https://github.com/okonet/lint-staged) on front-end code that will run eslint and prettier on your code before committing it. If there are linting errors and eslint isn't able to automatically fix it, the commit will not happen. You will need to fix the issue manually then attempt to commit again. Note: if you've already installed the [husky](https://github.com/typicode/husky) package at least once (used for precommit npm script), you will need to run `yarn --force` or `npm install --no-cache`. For some reason the post-install script of husky does not run, when the package is pulled from yarn's or npm's cache. This is not husky specific, but rather a cached package specific issue. ## Testing The following technologies are used for testing: - **Rspec** - **Capybara** with **selenium-webdriver** - **chromedriver-helper** for standard JS testing. - **`rack_session_access`** - **Warden** - **guard-rspec** for automated testing #### When should I use `login_via_session_as(:user)` vs `login_as(:user)`? - `login_as(:user)` uses Warden's stubbing actions to make the application think that a user is signed in but without all of the overhead of actually signing them in. Recommended for view test. - `login_via_session_as(:user)` uses `rack_session_access` to modify application's session. It is integrated with Devise so current_user won't be nil. Recommended for feature test. ## Previewing emails in development You can modify the test in `/test/mailers/previews` You can view the previews at (for example) `http://localhost:3000/rails/mailers/notify_mailer/new_reply_email` ## How to contribute (Internal) 1. Clone the project locally. 2. Create a branch for each separate piece of work. 3. Do the work and write [good commit messages](https://chris.beams.io/posts/git-commit/). - If your work includes adding a new environment variable, make sure you update `_env_checker.rb`. 4. Push your branch up to this repository. 5. Create a new pull-reqest. 6. After the pull-request is approved and merged, delete your branch on github. **Avoid pushing spike(test) branches up to the main repository**. If you must, push the spike branches up to a forked repository. ### Branch Policies #### Branch naming convention Name the branch in the following manner. `