├── .rspec
├── .haml-lint.yml
├── .rspec_parallel
├── .pronto.yml
├── product.md
├── LICENSE
├── .rubocop.yml
├── coffeelint.json
├── css.md
└── README.md
/.rspec:
--------------------------------------------------------------------------------
1 | --order rand
2 | --color
3 | --format progress
4 |
--------------------------------------------------------------------------------
/.haml-lint.yml:
--------------------------------------------------------------------------------
1 | linters:
2 | LineLength:
3 | max: 113
4 |
--------------------------------------------------------------------------------
/.rspec_parallel:
--------------------------------------------------------------------------------
1 | --format progress
2 | --format ParallelTests::RSpec::RuntimeLogger --out reports/parallel_tests/runtime_rspec.log
3 |
4 |
--------------------------------------------------------------------------------
/.pronto.yml:
--------------------------------------------------------------------------------
1 | all:
2 | exclude: [
3 | vendor/assets/**/*,
4 | bin/*,
5 | db/schema.rb,
6 | db/migrate/*
7 | ]
8 | AllCops:
9 | TargetRubyVersion: 2.4.1
10 |
--------------------------------------------------------------------------------
/product.md:
--------------------------------------------------------------------------------
1 | # Working with Clients
2 |
3 | * [Product strategy means saying no](https://blog.intercom.com/product-strategy-means-saying-no/)
4 | * Technical Debts:
5 | * [Ward Explains Debt Metaphor](http://wiki.c2.com/?WardExplainsDebtMetaphor)
6 | * [Video: Simplicity Matters by Rich Hickey](https://www.youtube.com/watch?v=rI8tNMsozo0&index=2&list=PLnBbQBvAzRj7eTqvZHHeoHGa2knP1l2wP)
7 |
8 | # Design Product
9 |
10 | * [Resources on GV Blog](https://library.gv.com/)
11 |
12 | # Schedule Development & Roadmaps
13 |
14 | * [Building Product Roadmaps](https://blog.intercom.com/mind-the-product-janna-bastow/)
15 |
16 | # Overall Product Owner Role
17 |
18 | * https://www.intercom.com/books/product-management
19 |
20 | # Team Playbooks
21 |
22 | * [The Atlassian Team Playbook](https://www.atlassian.com/team-playbook)
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 JetThoughts
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | AllCops:
2 | TargetRubyVersion: 2.4
3 |
4 | # For now our code is not ready, but we should fix it soon
5 | Style/FrozenStringLiteralComment:
6 | Enabled: false
7 |
8 | Lint/HandleExceptions:
9 | Exclude:
10 | - 'bin/rails'
11 | - 'bin/rake'
12 |
13 | # Configuration parameters: AllowURI, URISchemes.
14 | ClassLength:
15 | Max: 150
16 |
17 | Metrics/LineLength:
18 | Max: 113
19 |
20 | Metrics/MethodLength:
21 | CountComments: false
22 | Max: 20
23 |
24 | Metrics/BlockLength:
25 | Exclude:
26 | - "**/*_spec.rb"
27 |
28 | Style/Documentation:
29 | Enabled: false
30 |
31 | Style/EmptyLines:
32 | Exclude:
33 | - 'config/environments/development.rb'
34 |
35 | Style/EmptyLinesAroundBlockBody:
36 | Exclude:
37 | - 'db/schema.rb'
38 |
39 | Style/StringLiterals:
40 | Exclude:
41 | - 'db/schema.rb'
42 |
43 | Style/ExtraSpacing:
44 | Exclude:
45 | - 'config/environments/development.rb'
46 |
47 | Style/PredicateName:
48 | Exclude:
49 | - 'app/helpers/application_helper.rb'
50 |
51 | Style/ClassAndModuleChildren:
52 | EnforcedStyle: nested
53 | SupportedStyles:
54 | - nested
55 | - compact
56 | Exclude:
57 | - 'app/controllers/**/*.rb'
58 |
59 | Style/MultilineOperationIndentation:
60 | EnforcedStyle: indented
61 |
62 | Style/MultilineMethodCallIndentation:
63 | EnforcedStyle: indented_relative_to_receiver
64 |
65 | Style/AlignParameters:
66 | EnforcedStyle: with_fixed_indentation
67 |
68 | Lint/EndAlignment:
69 | EnforcedStyleAlignWith: variable
70 |
71 | Style/SafeNavigation:
72 | Enabled: false
73 |
74 | Style/AlignHash:
75 | EnforcedHashRocketStyle: key
76 | EnforcedColonStyle: key
77 | EnforcedLastArgumentHashStyle: always_inspect
78 |
79 | Style/MultilineMethodCallIndentation:
80 | EnforcedStyle: indented
81 |
82 | Style/NegatedIf:
83 | Enabled: false
84 |
85 | Style/GuardClause:
86 | Enabled: false
87 |
--------------------------------------------------------------------------------
/coffeelint.json:
--------------------------------------------------------------------------------
1 | {
2 | "arrow_spacing": {
3 | "level": "ignore"
4 | },
5 | "braces_spacing": {
6 | "level": "ignore",
7 | "spaces": 0,
8 | "empty_object_spaces": 0
9 | },
10 | "camel_case_classes": {
11 | "level": "error"
12 | },
13 | "coffeescript_error": {
14 | "level": "error"
15 | },
16 | "colon_assignment_spacing": {
17 | "level": "ignore",
18 | "spacing": {
19 | "left": 0,
20 | "right": 0
21 | }
22 | },
23 | "cyclomatic_complexity": {
24 | "level": "ignore",
25 | "value": 10
26 | },
27 | "duplicate_key": {
28 | "level": "error"
29 | },
30 | "empty_constructor_needs_parens": {
31 | "level": "ignore"
32 | },
33 | "ensure_comprehensions": {
34 | "level": "warn"
35 | },
36 | "eol_last": {
37 | "level": "ignore"
38 | },
39 | "indentation": {
40 | "value": 2,
41 | "level": "error"
42 | },
43 | "line_endings": {
44 | "level": "ignore",
45 | "value": "unix"
46 | },
47 | "max_line_length": {
48 | "value": 113,
49 | "level": "warn",
50 | "limitComments": true
51 | },
52 | "missing_fat_arrows": {
53 | "level": "ignore",
54 | "is_strict": false
55 | },
56 | "newlines_after_classes": {
57 | "value": 3,
58 | "level": "ignore"
59 | },
60 | "no_backticks": {
61 | "level": "error"
62 | },
63 | "no_debugger": {
64 | "level": "warn",
65 | "console": false
66 | },
67 | "no_empty_functions": {
68 | "level": "ignore"
69 | },
70 | "no_empty_param_list": {
71 | "level": "ignore"
72 | },
73 | "no_implicit_braces": {
74 | "level": "ignore",
75 | "strict": true
76 | },
77 | "no_implicit_parens": {
78 | "level": "ignore",
79 | "strict": true
80 | },
81 | "no_interpolation_in_single_quotes": {
82 | "level": "ignore"
83 | },
84 | "no_nested_string_interpolation": {
85 | "level": "warn"
86 | },
87 | "no_plusplus": {
88 | "level": "ignore"
89 | },
90 | "no_private_function_fat_arrows": {
91 | "level": "warn"
92 | },
93 | "no_stand_alone_at": {
94 | "level": "ignore"
95 | },
96 | "no_tabs": {
97 | "level": "error"
98 | },
99 | "no_this": {
100 | "level": "ignore"
101 | },
102 | "no_throwing_strings": {
103 | "level": "error"
104 | },
105 | "no_trailing_semicolons": {
106 | "level": "error"
107 | },
108 | "no_trailing_whitespace": {
109 | "level": "error",
110 | "allowed_in_comments": false,
111 | "allowed_in_empty_lines": true
112 | },
113 | "no_unnecessary_double_quotes": {
114 | "level": "ignore"
115 | },
116 | "no_unnecessary_fat_arrows": {
117 | "level": "warn"
118 | },
119 | "non_empty_constructor_needs_parens": {
120 | "level": "ignore"
121 | },
122 | "prefer_english_operator": {
123 | "level": "ignore",
124 | "doubleNotLevel": "ignore"
125 | },
126 | "space_operators": {
127 | "level": "ignore"
128 | },
129 | "spacing_after_comma": {
130 | "level": "ignore"
131 | },
132 | "transform_messes_up_line_numbers": {
133 | "level": "warn"
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/css.md:
--------------------------------------------------------------------------------
1 | #Jetthoughts CSS/SASS Style Guide
2 | _In our guide we combine rules from [AIRBNB](https://github.com/airbnb/css) style guide and [RSCSS](http://rscss.io/) naming conventions. Advanced rules can be taken from links above, else is presented in current guide._
3 |
4 | ## Components and Elements
5 | - All elements should be decomposed by the components. Each component should be placed in their own file.
6 | - Components should be named with at least two words, separated by a dash `-` . [More..](http://rscss.io/components.html)
7 | - Each component may have elements. They should have classes that are only one word. [More..](http://rscss.io/elements.html)
8 | - Components and elements may have a variants. Variants should be wrapped wit a separate class and will be prefixed with a dash `-`. [More..](http://rscss.io/variants.html)
9 |
10 | ##[File structure](http://www.sitepoint.com/architecture-sass-project/)
11 | How we might organize style files
12 | ```
13 | stylesheets/
14 | |
15 | |– base/
16 | | |– _reset.scss # Reset/normalize
17 | | |– _typography.scss # Typography rules
18 | | ... # Etc…
19 | |
20 | |– components/
21 | | |– _buttons.scss # Buttons
22 | | |– _carousel.scss # Carousel
23 | | |– _cover.scss # Cover
24 | | |– _dropdown.scss # Dropdown
25 | | |– _navigation.scss # Navigation
26 | | ... # Etc…
27 | |
28 | |– helpers/
29 | | |– _variables.scss # Sass Variables
30 | | |– _functions.scss # Sass Functions
31 | | |– _mixins.scss # Sass Mixins
32 | | |– _helpers.scss # Class & placeholders helpers
33 | | ... # Etc…
34 | |
35 | |– layout/
36 | | |– _grid.scss # Grid system
37 | | |– _header.scss # Header
38 | | |– _footer.scss # Footer
39 | | |– _sidebar.scss # Sidebar
40 | | |– _forms.scss # Forms
41 | | ... # Etc…
42 | |
43 | |– pages/
44 | | |– _home.scss # Home specific styles
45 | | |– _contact.scss # Contact specific styles
46 | | ... # Etc…
47 | |
48 | |– themes/
49 | | |– _theme.scss # Default theme
50 | | |– _admin.scss # Admin theme
51 | | ... # Etc…
52 | |
53 | |– vendors/
54 | | |– _bootstrap.scss # Bootstrap
55 | | |– _jquery-ui.scss # jQuery UI
56 | | ... # Etc…
57 | |
58 | |
59 | – main.scss # primary Sass file
60 | ```
61 |
62 | ## [CSS](https://github.com/airbnb/css#css)
63 | - Use soft tabs (2 spaces) for indentation
64 | - Prefer dashes over camelCasing in class names.
65 | - Use classnames whenever possible. Tag selectors are fine, but they may come at a small performance penalty and may not be as descriptive.
66 | - Do not use ID selectors
67 | - When using multiple selectors in a rule declaration, give each selector its own line.
68 | - Put a space before the opening brace `{` in rule declarations
69 | - In properties, put a space after, but not before, the : character.
70 | - Put closing braces `}` of rule declarations on a new line
71 | - Put blank lines between rule declarations
72 |
73 | ## [Sass](https://github.com/airbnb/css#sass)
74 | - Use `.scss` format instead of `.sass`
75 | - Order your @extend, regular CSS and @include declarations logically ([More...](https://github.com/airbnb/css#ordering-of-property-declarations))
76 |
77 | ## [Nested selectors](https://github.com/airbnb/css#nested-selectors)
78 | - Do not nest selectors more than three levels deep! If it's necessary here are some [guidelines](http://rscss.io/nested-components.html) for doing that.
79 |
80 | ## [JavaScript in Css](https://github.com/airbnb/css#javascript-hooks)
81 | - Avoid binding to the same class in both your CSS and JavaScript. Please create JavaScript-specific classes to bind to, prefixed with `.js-`
82 |
83 | ## [Layouts](http://rscss.io/layouts.html)
84 | * Components should be made in a way that they're reusable in different contexts. Avoid putting these properties in components:
85 | * Positioning (position, top, left, right, bottom)
86 | * Floats (float, clear)
87 | * Margins (margin)
88 | * Dimensions (width, height) *
89 |
90 | [More information](http://rscss.io/layouts.html)
91 |
92 | ## [Mixins](https://github.com/airbnb/css#mixins)
93 | - Mixins, defined via @mixin and called with @include, should be used sparingly and only when function arguments are necessary. A mixin without function arguments (i.e. `@mixin hide { display: none; }`) is better accomplished using a placeholder selector ([More...](https://github.com/airbnb/css#placeholders)) in order to prevent code duplication.
94 |
95 | ## [Helpers](http://rscss.io/helpers.html)
96 | - For general-purpose classes meant to override values, put them in a separate file and name them beginning with an underscore. They are typically things that are tagged with `!important`. Use them very sparingly.
97 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | JTology - How We Work
2 | ===========
3 |
4 | ## Values & Core Principles
5 |
6 | * Fairness
7 | * Joy
8 | * [Kaizen](https://en.wikipedia.org/wiki/Kaizen)
9 |
10 | ## Other Guides:
11 |
12 | * [For Product Owners](product.md)
13 | * [Thoughtbot's Guides](https://github.com/thoughtbot/guides)
14 |
15 | ## Base Strucutring Projects
16 |
17 | * SCSS: Structure is based on [RSCSS](https://github.com/rstacruz/rscss)
18 | * Vanila JavaScript: Strucutre is based on [RSJS](https://github.com/rstacruz/rsjs)
19 | * Other common structure of JavaScript Page logic: https://github.com/tastejs/todomvc/blob/gh-pages/examples/jquery/js/app.js
20 |
21 | ## Formatting/Conventions
22 |
23 | Base styles guides:
24 |
25 | * Ruby - [bbatsov/ruby-style-guide](https://github.com/bbatsov/ruby-style-guide)
26 | * CSS - [JT CSS Style Guide](https://github.com/jetthoughts/how-we-work/blob/master/css.md)
27 | * JavaScript - [airbnb/javascript](https://github.com/airbnb/javascript)
28 |
29 | Our updates:
30 |
31 | * Limit lines to 110 characters, in order to remove horizontal scrolling on GitHub when we are doing code review
32 | * Align parameters like:
33 |
34 | ```ruby
35 | # good (normal indent) PREFERABLE
36 | def send_mail(source)
37 | Mailer.deliver(
38 | to: 'bob@example.com',
39 | from: 'us@example.com',
40 | subject: 'Important message',
41 | body: source.text
42 | )
43 | end
44 |
45 | # not so bad
46 | def send_mail(source)
47 | Mailer.deliver(
48 | to: 'bob@example.com', from: 'us@example.com'
49 | )
50 | end
51 |
52 | # good, but DEPRECATED
53 | def send_mail(source)
54 | Mailer.deliver(to: 'bob@example.com',
55 | from: 'us@example.com',
56 | subject: 'Important message',
57 | body: source.text)
58 | end
59 | ```
60 | * Use prefix `_` for memo variables:
61 |
62 | ```ruby
63 | class TestObject
64 | attr_reader :attr_name
65 |
66 | def attr_name
67 | @attr_name ||= lazy_calculation_for_attr_name
68 | end
69 |
70 | def public_method_with_memo
71 | @_public_method_with_memo ||= public_method_with_memo_calculcations
72 | end
73 | end
74 | ```
75 |
76 | * Stick to [Newlines](https://github.com/airbnb/ruby#newlines) section of Airbnb's Ruby style guide for grouping the code within methods.
77 |
78 | ## Working with Bugs
79 |
80 | * Confirm on the master, the staging and finally on development environment.
81 | * Add tests with reproduced bugs before add fixes
82 |
83 | ## Ruby on Rails Conventions
84 |
85 | * We use Decorators (in code we called them `Carrier`) as View and Form objects: [introduction how to use them](https://goo.gl/photos/nN1yNNqUoyKEK6an7)
86 | * We do not use full Presenters (TODO: add link to first post about them) with any tag generations
87 | * We do not overuse of [Concerns](https://blog.codeship.com/when-to-be-concerned-about-concerns/)
88 | * We do not overuse (in 99% of our code we do not see such stuff): `send`, `&.`, `**`. To prevent misusage of Ruby Syntax Sugars [[link](#prevent-syntax-sugar-overuse)]
89 |
90 | ## Test Conventions
91 |
92 | ### Principles
93 |
94 | * TDD
95 | * Clarity means that a test should serve as readable documentation for humans, describing the code being tested in terms of its public APIs.
96 | * A test is complete when its body contains all of the information you need to understand it, and concise when it doesn't contain any other distracting information.
97 |
98 | Ref: [Testing on the Toilet: What Makes a Good Test?](https://testing.googleblog.com/2014/03/testing-on-toilet-what-makes-good-test.html)
99 |
100 | ### Rules
101 |
102 | * Tests First[[link](#tdd-tests)]
103 | * Use Black Box testing strategy (there is no other way to support TDD)[[link](#black-box-tests)]
104 |
105 | By ignoring the code (Black box testing), it demonstrates a different value system - the tests are valuable alone.
106 | * We use the meaningful names in the test cases. It makes easier to understand the business logic.[[link](#meaningful-names-in-tests)]
107 |
108 | ```ruby
109 | # bad
110 | def test_email_is_normalized
111 | user = User.create! email: 'Foo@quux.com'
112 | assert_equal 'foo@quux.com', user.email
113 | end
114 |
115 | # good
116 | def test_email_is_normalized
117 | user = User.create! email: ' thisIsAMixedCaseEmail@example.com'
118 | assert_equal 'thisisamixedcaseemail@example.com', user.email
119 | end
120 | ```
121 | * The test is building or referencing a larger fixture than is needed to verify the functionality in question. Do not load more data than needed to test your code. For each test create exactly what it needs and not more. More variations provides more complexities. More details could be found on http://xunitpatterns.com/Obscure%20Test.html#General%20Fixture [[link](#big-fixtures-in-tests)]
122 |
123 | Message for reviewer:
124 |
125 | > Each check must be isolated and shouldn't depend or interfere with others. This will make your tests clear and well organized and help to clearly see the cause of the failure. Please check https://github.com/jetthoughts/how-we-work/blob/master/README.md#big-fixtures-in-tests
126 |
127 | ```ruby
128 | # BAD
129 | let!(:user_with_big_name) { ... }
130 | let!(:user_with_small_name) { ... }
131 |
132 | it 'this test use only user_with_big_name' { expects(response).to have(user_with_big_name) }
133 | it 'this test use only user_with_small_name' { expects(response).to have(user_with_small_name) }
134 | ```
135 |
136 | ```ruby
137 | # GOOD
138 | context 'with big name' do
139 | let(:user) { ... }
140 |
141 | it 'this test use only user_with_big_name' { expects(response).to have(user) }
142 | end
143 |
144 | context 'with small name' do
145 | let(:user) { ... }
146 |
147 | it 'this test use only user_with_small_name' { expects(response).to have(user) }
148 | end
149 | ```
150 |
151 | ```ruby
152 | # BAD
153 | setup do
154 | big_file_with_all_users = compile_file_from_users(User.all)
155 | end
156 |
157 | test 'this test use only user_with_big_name' { assert_includes big_file_with_all_users, 'magic string with all big letter' }
158 | test 'this test use only user_with_small_name' { assert_includes big_file_with_all_users, 'magic string with all small letter' }
159 | ```
160 |
161 | ```ruby
162 | # GOOD
163 | test 'this test use only user_with_big_name' do
164 | result = compile_file_from_users(User.new(name: 'Big Name'))
165 | assert_includes result, 'Big Name'
166 | end
167 |
168 | test 'this test use only user_with_small_name' do
169 | result = compile_file_from_users(User.new(name: 'Samll Name'))
170 | assert_includes result, 'Small Name'
171 | end
172 | ```
173 |
174 | * No Dynamic Test generation.[[link](#dynamic-cases-in-tests)]
175 |
176 | ```ruby
177 | # BAD
178 | { string: 'zone_id', array: %w[zone_id], hash: { "0" => "zone_id" } }.each do |type, group_by|
179 | it "returns valid json if group_by is #{type}" do
180 | end
181 | end
182 | ```
183 |
184 | ```ruby
185 | # GOOD
186 | it "returns zone_id json if group_by is string" { }
187 | it "returns [zone_id] json if group_by is array" { }
188 | it "returns { '0' => 'zone_id' } json if group_by is hash" { }
189 | ```
190 | * Irrelevant Information[[link](#irrelevant-information)]
191 |
192 | Message for reviewer:
193 |
194 | > The test is exposing a lot of irrelevant details about the fixture that distract the test reader from what really affects the behavior of the subject under test.
195 |
196 |
197 | ```ruby
198 | describe 'PUT Update' do
199 | let!(:user) { create :user }
200 |
201 | # Bad
202 | it 'updates user' do
203 | attributes = { first_name: '..', last_name: '..', role: '..', email: '..' }
204 | put: :update, params: { attributes }
205 | expects(response.body).to eq attributes
206 | end
207 |
208 | # Good
209 | it 'updates first_name' do
210 | put: :update, params: { first_name: 'John Dou' }
211 | expects(response.body).to have_attribute { first_name: 'John Dou' }
212 | end
213 |
214 | it 'updates email' do
215 | put: :update, params: { email: 'email@example.com' }
216 | expects(response.body).to have_attribute { email: 'email@example.com' }
217 | end
218 | ```
219 |
220 | ## Setup Development Environment
221 |
222 | * `bin/setup` - cold setup
223 | * `bin/update` - update environment on new code updates
224 |
225 | ## Delivery Flow
226 |
227 | Our flow is based on GitHub flow with Heroku Review
228 |
229 | * create PR (we convert issues into PR)
230 | * deploy PR to Heroku (we use Heroku Review to do this automatically)
231 | * verify on Heroku yourselves
232 | * ask verify, to code review and to merge (we have Code Review)
233 |
234 | ## TODO/FIXME Notes
235 |
236 | * add issue on GitHub per each note
237 | * create TODO/FIXME note in the code
238 | * add in code's note link to GitHub's issue
239 |
240 | ## Git/GitHub
241 |
242 | * [Basic git crash course for minimum git commands enough to work on the project](https://jtway.co/how-do-we-git-it-in-jetthoughts-a002b4dba223)
243 | * Prefix feature branch names with issue number: *123-issue-name*;
244 | * Do not mess with cosmetics changes. Move them in separate commit or pr;
245 | * Squash multiple trivial commits into a single commit;
246 | * Convert an existing issue into a pull request: `hub pull-request -i 123`;
247 | * Write a good commit message based on http://chris.beams.io/posts/git-commit/ with some requirements[[link](#git-commit-message)]:
248 | ```
249 | Capitalized, the imperative mood, short (50 chars or less) subject (#)
250 |
251 | Body after space line. Wrap the body at 72 characters.
252 | Use the body to explain what and why.
253 |
254 | Closes #, fixes #
255 | ```
256 | Also some examples:
257 |
258 | * http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
259 | * https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message
260 | * https://github.com/RomuloOliveira/commit-messages-guide
261 |
262 | * Create Issue Template[[link](#git-issue-template)]
263 | * **Title:** Jobs to be done
264 | * **Body:**
265 |
266 | *1. Acceptance Criteria*
267 |
268 | Acceptance criteria is that a developer knows they need to complete before that issue can be considered 'done'.
269 | They are the points against which the issue will be tested.
270 |
271 | *2. A screenshot or mock up of a new design*
272 |
273 | A picture which illustrates what the issue should be creating or a screenshot of an existing page showing where a bug is occurring.
274 | Remember to include mock ups of both mobile and desktop views.
275 |
276 | * Tutorials:
277 | * https://www.atlassian.com/git/tutorials/
278 | * http://git-scm.com/docs/gittutorial
279 | * https://try.github.io/
280 |
281 | ## Development Best Practices
282 |
283 | * [Exceptions should be exceptional](https://jacopretorius.net/2009/10/exceptions-should-be-exceptional.html)
284 | * [KISS ... your ARSE :P](http://code.mumak.net/2012/02/simple-made-easy.html)
285 | * Stub/Mock only external services or code with hard simulation: https://www.youtube.com/watch?v=z9quxZsLcfo&feature=youtu.be&t=21m00s
286 | * [Four-Phase Test](http://xunitpatterns.com/Four%20Phase%20Test.html)
287 |
288 | ## Other Tools and Practices to use
289 |
290 | * [UX from Good UI](http://www.goodui.org/)
291 | * [Material design](https://material.io/)
292 |
293 | ## Recomended Tutorials
294 |
295 | * HTML/CSS3:
296 | * [Learn CSS Layout](http://learnlayout.com/)
297 | * [A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
298 | * Web Performance:
299 | * [Website Performance Optimization: The Critical Rendering Path](https://www.udacity.com/course/ud884)
300 | * ES6: https://www.eventbrite.com/engineering/tag/learning-es6/
301 | * React.js/Redux: https://egghead.io/browse/frameworks/react
302 |
303 |
304 | ## Constraints which makes fun development
305 |
306 | * 2 days per PR
307 | * 2 Issues/PR per Developer
308 | * [1000/100/6 performance model](https://www.paulirish.com/2015/advanced-performance-audits-with-devtools/)
309 | * 5 min to pass all test suites
310 | * 20 sec to run one test
311 | * 20 sec to boot
312 |
313 | ## Tools:
314 | * Collaboration:
315 | * Chat: [Discord](https://discordapp.com/)
316 | * Issues Plannings: [Github](https://github.com), [Trello](https://trello.com)
317 | * Information board: [Trello](https://trello.com)
318 | * Screenshots: [CloudApp](https://www.getcloudapp.com/), [Joxi](http://joxi.net/) (Ubuntu)
319 | * Screencast: [Loom](https://www.useloom.com), Kazam (Ubuntu)
320 | * Video call: [Appear.in](https://appear.in/)
321 | * CI:
322 | * [CircleCI](https://circleci.com/)
323 | * Server Configuation: [Ansible](https://www.ansible.com/)
324 | * Deployments: Capistrano
325 | * Assets and File Uploads CDN hosting: AWS, CloudFront, Cloudinary (Images Uploads)
326 | * PAAS for Isolated Staging Testing: [Heroku](https://heroku.com) (Ruby on Rails apps), [surge.sh](http://surge.sh/) (Static HTML)
327 | * Cache: Memcached/Redis Cloud from Redis Lab
328 | * JavaScript Base Frameworks: [Stimulus](https://github.com/stimulusjs/stimulus), Vanilla JS, [Vue.js](https://vuejs.org/), [React](https://reactjs.org/)
329 | * SCM: [GitHub](https://github.com)
330 |
--------------------------------------------------------------------------------