Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The general approach to branching used within the organisation.
Inherits the process from https://nvie.com/posts/a-successful-git-branching-model/
🌞 Good branch names:
nice-kebab-cased-titles
fixes-footer-links
4411290-setup-state-management-integration
feature/new-design
hotfix/db-connection
release-1.2.3
⛈ Bad branch names:
patch-1
- not enough context
camelCasedBranchNames
- camelcase
PascalCasedBranchNames
- pascal case
long-titles-above-80-chars-{.....}
- too long
#58/something
- shell understands it as comment
Branching model
Merges
Dev docs for the Podkrepi.bg organisation.
Our documentation is publicly accessible for everyone to read and contribute to. All current and future contributors are encouraged to read the Dev Guidelines
section as a starting point.
Our weekly development meeting takes place every Saturday between 6pm - 7:30pm EEST (UTC+3) in the discord server of the organisation. All issues regarding development can be discussed during these meetings and everyone is welcome to join!
An unwritten contract signed by everyone in the organisation.
We use the definition of done to asses whether or not an enhancement can be considered to be complete (shippable to production).
DoD is our general framework to derive and end-to-end process which ensures every common piece of work meets the organisation's quality standards. Whereas, AC is a set of strictly defined targets for each individual (functional) piece of work that must be met before a task is considered to be complete.
It is vital that every contributor in our organisation is aware of and understands our DoD. This helps us:
Complete all tasks without introducing any gaps in the process.
Follow with clarity where we are on our roadmap and what has been completed.
Know what is expected from every contributor.
Meet a certain quality of our work which leads to:
Lowering the amount of time spend for reworks.
Delivering on our promise to create a platform which makes a difference in our society.
The following is a general approach towards DoD, each team is encouraged to derive their own process suitable for the team's functionality in the organisation.
Code and unit tests for functionality completed.
Assumption of meeting Acceptance Criteria.
Premerge [if applicable] tests and code reviews passed.
Postmerge [if applicable] tests passed.
Project builds with no failures.
Project deployed to dev environment.
Initial QA performed by the developer. [if this step fails, go back to step 1]
Feature documentation [if applicable] and tests documentation [if applicable] written.
Feature QA'ed by a QA engineer against the acceptance criteria. [if this step fails, go back to step 1]
Official documentation updated.
Feature marked as completed.
All features included in the release are marked as completed. Where a feature is not yet completed, the feature is postponed for the next release.
Update changelog and release documentation where applicable.
Current environment is "green" - all unit, functional, integration, E2E and other possible tests are passing.
Release acceptance criteria is met. [If this step fails, go back to step 1]
QA functionality of the platform. [If this step fails, go back to step 1]
QA if any experimental features are exposed to the end user. [If this step fails, go back to step 1]
Promote the release to the next environment in the pipeline.
Release successfully deployed to new environment. [If this step fails, go back to step 1]
Release marked as completed.
We're integrated with https://allcontributors.org/ bot
Comment on this issue, asking @all-contributors bot to add a contributor:
<contribution>
: See the Emoji Key (Contribution Types Reference) for a list of valid contribution types.
Wondering how to write a good PR up to the organisation's standards?
Pull requests are official record of all changes we make. As an open source organisation PRs might be read from multiple people and not only the assigned reviewers. Future contributors are likely to search and come back to past PRs for a variety of reasons, therefore, it is vital that the important changes are not only in the code but also included in the description. Always think about the reviewers and potential future readers!
The title is what usually appears in the version control. Thus, it must be a full, clear and imperative sentence.
Bad title example:
Deleting API endpoint and adding new one
- not specific enough, not imperative, bad wording.
Good title example:
Delete the /foo/bar REST endpoint and replace it with /foo/baz
The latter example describes the specific change made, improves the searchability and gives enough information to the reader which allows them to skim through the changes rather than spending more time going through the rest of the description.
Keep the body as informative as possible. Start with outlining the problem you are trying to solve/the feature you want to add.
All readers must get a perfect impression of what the change is and reason/motivation behind it. Think about any attachments that might be useful. Add screenshots if the changeset leads to visual difference in the frontend, add any external link/references to any design docs that might help the reader to better understand context of/changes in the PR. However, try to keep those to a minimal and outline as much as possible in the written description as any external resources can easily be deleted in the future or problems with access permissions might occur.
Do not skip any important information. Outline with clarity the alternative solutions and the reasons for avoiding those. Similarly, it is vital to explain any shortcomings of the approach that you took to solving the problem, what can possibly go wrong in the future and how we can possibly overcome those issues if you can think of any.
10 lines of code = 10 issues, 500 lines of code = LGTM!... code reviews in a nutshell...
Your PR changeset size should be just right, i.e. one self-contained change per PR! Furthermore, you should strive to limit your changeset to 250-300 lines of code where possible (source, source). This is beneficial for both the reviewers and authors. As a reviewer you will be able to go through the changes much quicker and provide a better feedback as the quantity of changes you are reviewing is less and the amount of context needed is proportional to the size. Vice-versa, as an author you will get good feedback fast and hoping for less potentially introduced bugs. Moreover, changes you will be required to make upon receiving the feedback would be less and easier to do, i.e. you will have to do less work if something is rejected. Small PRs are also easier to design and the mergeability and simplicity of rolling back the changes increase substantially.
For example: you want to add a new feature for creating a product, your changes will include a new public API endpoint and its backend implementation. Instead of dumping all of your changes in a massive PR, you can break down your issue similarly to:
A differential with any Database schema changes required.
A differential with any protobuf changes required.
Initial commit with stubs for the backend.
A series of differentials containing the backend implementation and respective unit tests.
A differential with any changes required to the public API.
Stacking PRs greatly improves the efficiency of the above process, you can see more examples how to this here.
Tests for new functionality must go in the same PR as the functional changes, do not try to reduce the changeset size by splitting unit tests from functional changes.
Do not mix changes - refactoring, bug fixing and enhancements must not go in the same differential.
It is inevitable that sometimes larger PRs will be needed - when refactoring code, code added by automation, deleting files etc. This is always fine as long as you have considered all options how to avoid the massive change but nothing seems to help.
The system's functionality must always be intact after merging the changes. We understand it is impossible for this rule not to be broken ever. But, introducing PRs that intentionally add a breaking change (even for a short period of time until your subsequent PR is merged) is unacceptable! There are a number of ways to avoid those and if unsure, ask your friendly community members for how to approach the problem.
The (written) unwritten guide to pull requests
Best Practices for Code Review
A common way to sort the imports in the file is by their source: external
, absolute
, relative
separated by an empty line. Each of those groups can be sorted by line length, but that's not super important.
Inherits AirBnb naming convention https://github.com/airbnb/javascript/tree/master/react#naming
Use PascalCase for React components and camelCase for their instances
Pascal cased file names src/components/GenericForm.tsx
Filename and default component of the file should have the same name.
Camel cased file names src/utils/hooks/useUser.ts
Lowercase kebab cased folders src/components/common/password-reset/ResetForm.tsx
Lowercase kebab cased files located in src/pages/sample-page.tsx
which correspond to /sample-page
url.
The common convention is that the main type of the component's props is called after the component itself with suffix -Props
. Prop types of AdvancedForm
becomes AdvancedFormProps
.
Nice IDE support and readability
Named function
Const arrow function
Discouraged as hooks cannot be used inside the class components
There are three common ways to style a component:
<Box />
componentSingle component that inherits all sizing props from MUI https://material-ui.com/system/basics/#all-inclusive
useStyles()
hookNext.js supports SCSS out of the box. Read more at https://nextjs.org/docs/basic-features/built-in-css-support#sass-support
File convention is based on a suffix .module.scss
(ex. about.module.scss
)
Simple strings are mapped directly to their respective translation
Complex translation keys are being evaluated upon translation
Commonly used translations with the same translation key
Custom translations with keys defined right next to the form
Default namespace is called common
and contains translations used on all pages (Layout, Nav, etc) and is stored at frontend/public/locales/{locale}/common.json
Namespaces (scopes, domains) are stored in separate json files at frontend/public/locales/{locale}/{namespace}.json
One namespace can combine the translations keys from several pages with common reusable strings ex. auth
scope collects keys for login
and register
pages.
It is preferred to use for translation keys and extract another level of nesting when the common prefix of the keys is above 3 or makes sense to be separated as new keys might be added in the future.
Namespace is separated with :
Translation nesting levels are separated with .
Words in a translation key are separated with -
domain:pages.nested-level.another-nested-level.translation-key
Usage of translation hook useTranslation
is preferred over usage of <Trans />
component, whenever possible.
Install kubectl
Install kustomize
You may trigger staging release at any point of time from the master
branch by:
This will update the deployment using ghcr.io/podkrepi-bg/frontend:master
image
The following command will:
Bump the version in package.json
Tag the latest
master branch
[postversion
] Push local tags to the remote origin
Update the image newTag
version in frontend/manifests/overlays/production/kustomization.yaml
Commit and push the manifest update
Once the image has been built by the GitHub Actions and is present in the Docker image repository you may trigger the actual deployment to the cluster.
You may trigger staging release at any point of time from the master
branch by:
This will update the deployment using ghcr.io/podkrepi-bg/api:master
image
The following command will:
Bump the version in package.json
Tag the latest
master branch
[postversion
] Push local tags to the remote origin
Update the image newTag
version in backend/manifests/overlays/production/kustomization.yaml
Commit and push the manifest update
Once the image has been built by the GitHub Actions and is present in the Docker image repository you may trigger the actual deployment to the cluster.
If you want to set a specific version for the deployment image you can do that by editing backend/manifests/overlays/production/kustomization.yaml
Allows attaching static props to the function
Nice for locally defined components
Okay for default exports, but not preferred
Unnamed arrow function
Class components
Nice for quick layouts that should follow the theme
Not the best for custom scenarios with more than _six props passed to it. Use hooks
instead
Not nice when the children have clear nesting structure of more than _three levels. Use hooks
or scss
instead
Nice for very specific styling that leverages theme
methods and props
Too verbose for simple use cases, if it contains less than 2 css rules. Use Box
instead
Not the best when dealing with styling of deep nested structures within the same component. Use scss
instead
Nice when dealing with complex nested structures that are scoped in a single component. When dealing with sub-components we're not sure if some of the rules will be left unused.
Too verbose for simple use cases, if it contains less than 2 css rules in a dedicated file. Use Box
instead
Cannot use theme support or theme variables Use hook
instead
POST
https://api.podkrepi.localhost/api/v1/support-request
Name | Type | Description |
---|---|---|
GET
https://api.podkrepi.localhost/api/v1/support-request
This endpoint allows you to get free cakes.
GET
https://api.podkrepi.localhost/api/v1/support-request/:id
DELETE
https://api.podkrepi.localhost/api/v1/support-request/:id
POST
https://api.podkrepi.localhost/api/v1/contact
Name | Type | Description |
---|---|---|
GET
https://api.podkrepi.localhost/api/v1/contact
This endpoint allows you to get free cakes.
GET
https://api.podkrepi.localhost/api/v1/contact/:id
DELETE
https://api.podkrepi.localhost/api/v1/contact/:id
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Authentication
string
Authentication token to track down who is emptying our stocks.
id
string
ID of the cake to get, for free of course.
Authentication
string
Authentication token to track down who is emptying our stocks.
person
object
support_data
object
Authentication
string
Authentication token to track down who is emptying our stocks.
ID
string
Authentication
string
id
string
Authentication
string
string
phone
string
company
string
message
string
firstName
string
lastName
string
Authentication
string
Authentication token to track down who is emptying our stocks.
ID
string
Authentication
string
id
string
Authentication
string