Conventions

GitHub

  • Try to add the ticket number to any related commit. Add the ticket number anywhere in the description of the commit.

    • Your commits should contain a reference to the JIRA issue, if:

      • you’re working on a customer project
      • you’re working on a closed-source library, such as Mayd
  • A pull request title should be build like this: (TEST-123, TEST-345) This is the title [req #4 #5]

    • Use a descriptive title.
    • Optional: if your pull request needs another PR as dependency, list the requirements in square brackets.
    • Add the ticket keys (in the same formatting as they are in JIRA) in regular braces, separated by comma.
  • As the author of a pull request, you’re responsible to invite appropriate reviewers.

    • Most repositories will have one or more default reviewers set, these are usually lead developers for the project or similar.
    • Despite this it is a good idea to manually invite anyone for whom the code you touched may be interesting/relevant or who could have good insights into it: your colleagues working on the same functionality, those you know have prior experience with it, specific developers for whom you would like to review your code, senior developers responsible for it, etc.
    • The larger the PR is, the better it is to invite more than one reviewer.
    • Use your own judgement according to the above guidelines!
  • As the author of a pull request, you’re responsible to get it merged.

    • Every PR needs to be approved by at least one reviewer before it can be merged.
    • If you invited multiple reviewers, for smaller pull requests it is enough to merge them after only one approval, as long as that reviewer has enough knowledge of the subject that you can rely on them to catch any critical issues and to suggest any important changes. Other reviewers you invited can do their reviews after the merge, and you can address their suggestions in your next PR.
    • Of course, this is for cases when one reviewer approves a PR and others haven’t reviewed it yet; don’t merge a PR if someone approved it but somebody else requested changes.
    • The larger, more “important” and more likely to influence multiple parts of the application a PR is, the more reviewers should approve it before merge. We don’t want to set any hard criteria on the number of approvals here because we want you to use your own judgement!
  • As the author of a pull request, you’re responsible for updating the corresponding JIRA issue into its appropriate state. That means it needs to be transitioned from In Progress to In Review upon opening the pull request, and from In Review to Done as soon as all pull requests for that issue have been merged.

Pull Requests

Each and every project has the following labels: needs-review, needs-work, suspended, waiting-for-dependencies, work-in-progress. There are a few rules and work-flows associated with each label:

  • needs-review: A pull request is ready to be reviewed
  • needs-work: Feedback has been provided and needs to be incorporated by the pull request author
  • suspended: The pull request is momentarily suspended and is waiting for an decision to be made where most commonly a given features is no longer needed or simply postponed
  • waiting-for-dependencies: This label is most commonly used when another pull request, there this one depends on, is still waiting to be merged (and released as a new version). Additionally to listing your dependencies in the pull request’s title, please also list them as part of your description, especially for things that aren’t necessarily under our own control, like dependencies on third-party projects. The pull request is usually not being reviewed and needs to be rebased first by the pull request author before it’s ready to be reviewed
  • work-in-progress: A pull request where the author is still actively working on. Most commonly used to share a specific subset or feature of a pull request with a colleague or as an active reminder for the author himself/herself. work-in-progress pull requests are not being reviewed unless it’s explicitly requested with the needs-review label. Alternatively, you can also use the draft feature that lets you open your new pull request as a draft, which can’t be automatically/accidentally merged as it needs to be converted into a regular pull request first.

More common use-cases

I’m creating a pull request and it’s asking/recommending me to provide an assignee and milestone feature, what do I need to do?

It’s not necessary to use these features for our pull requests, as we’re not using GitHub milestones or use the issue and pull request assignments. The only fields you need to provide are the reviewers and labels fields, as the reviewers are only looking at pull requests that have the label needs-review.

I’m building a prototype or I’m not entirely sure with the direction my PR is heading and I need early feedback, what do I need to do?

This is the perfect example when you should open a draft pull request. Please set the work-in-progress and needs-review label, so it gets picked up by the reviewers.

I’ve got feedback on my pull request, what do I need to do?

Use the provided feedback as a check-list and mark all discussions as resolved (“resolve conversation”). Resolving feedback discussions is a great way to keep track of what feedback you’ve already worked on, especially in larger review sessions. This also helps the reviewer to quickly see which feedback needs further discussion if a few of them aren’t resolved. If some feedback is unclear or needs further discussion, feel free to reply. If you shouldn’t receive feedback in an appropriate time span, please approach and encourage the reviewer to reply. Wait for the build pipeline to check your changes and determine everything is good before changing the label back to needs-review.

A pull request I’m reviewing needs to be rebased due to a merge conflict, what should I do?

Leave a friendly comment about that and change the label to needs-work.

The build pipeline is failing and complaining about code that I haven’t touched?

This happens occasionally when project dependencies have been updated or your changes conflict with existing code. Never the less you should always leave the code cleaner than you found it thus fixing the errors shown in the pipeline.

I’ve merged a pull request, is there anything else I need to do?

If the pull request as linked to a JIRA issue, please check whether its current status is in-review. If so, feel free to resolve the issue. If the JIRA status is open and you’re not sure what to do, it’s best to approach the pull request’s author and ask him what to do about the JIRA issue, as he/she may have forgot to change the JIRA issue status or that there are some follow-up pull requests still being worked on, hence why it wasn’t changed to in-review.

Please make sure the pull request’s branch has been deleted so we only have active branches

I’ve filed a pull request that adds UI, is there anything I need to do?

Please provide screenshots or GIFs of Gluggi and/or the website, so the reviewer knows how the UI is supposed to look like and and can provide better feedback.

My pull request has more than 1.000 lines added (excluding lock-files), what do I need to do?

Please keep the pull requests as small as possible. The larger the pull requests, the worse the feedback gets as the cognitive load is too high to provide useful feedback. To prevent this issue from happening, we decline any pull request that is larger than said limit. If you encounter this situation, please split your pull request into multiple smaller ones, e.g. one pull request only adds entities, the other some frontend logic, another one something completely different.

I’m working on a large feature that I need to split into multiple pull requests, what do I need to do?

Please make sure that each and every pull request is self-contained and doesn’t crash the app. You can achieve this either by uncommenting specific lines that runs your new code or by using something like a Feature Flag, where your feature is being controlled by a flag that is either set in a config file or in the database, e.g. via Mayd.

NPM

  • The npm client is used, yarn is not used (anymore). Add the package-lock.json to the repository and remove any existing yarn.lock.

Composer

  • Every project has a package name in the format bklyn/client.project, where client and project are lower-snake-case.

    Example: bklyn/bemo.website-2018

  • All projects are published on private packagist.

Symfony

  • Start your project with the newest Symfony version.

Directory Layout

  • Only define the most global routes in config/routes.yaml, for example login and homepage (if required).
  • All other routes: put them in separate files in config/app_routes/.
  • Your main config/routes.yaml should only consist of imports of the app_routes (and the few global routes). First the global routes, than the imports.

    • Prefix all names of imports with _import.

Controllers

  • Use service argument injection.
  • For dependencies of private helper methods, you can extend the getSubscribedServices() implementation, to be able to fetch these services inside the private helper directly.
  • Order your action arguments like this:

    1. Services (like models, Translator, helpers, …)
    2. Special symfony core variables (like Request)
    3. The parameters of your action, as defined in the routing
  • Every public method in a controller must be an action (and should have a route pointing to it).
  • Actions returning JSON must always return an object instead of an array

    1. You are forward compatible if you need an additional item in the future
    2. You don’t introduce local security issues, due to the way JSON constructs arrays in JavaScript

Routing

  • Route import names should start with _import.*

Services

  • Use single quotes and only quote when necessary.
  • Sort service names alphabetically.
  • Order in the file:

    1. _defaults
    2. Directory-based service definitions
    3. Regular service definitions
  • Use autoconfiguration and autowiring.
  • Explicitly list imported directories (allowlist) if you are importing from the root directory (like in a reusable bundle):

    Mayd\Core\:
        resource: '../../{Command,Config,Controller,...,User,Validation/Validator}/*'
  • When only importing from src/, you can use a denylist (like in a regular app):

    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
  • Bind parameters via arguments.

    Service:
        $isDebug: '%kernel.debug%'
  • Avoid using name-based bindings in _defaults, except for the parameters $projectDir (%kernel.project_dir%) and $isDebug (%kernel.debug%). These can be bound service-file-wide as shown:

    services:
        _defaults:
            bind:
                $isDebug: '%kernel.debug%'
                $projectDir: '%kernel.project_dir%'

Translations

  • Don’t translate default Symfony validation messages (you should use the Becklyn RAD Bundle, as it improves some messages).
  • Use translation keys instead of translation strings:

    {# GOOD #}
    {{ "example.message" | trans }}
    
    {# BAD #}
    {{ "This is a message" | trans }}
  • In Twig, prefer {{ "text" | trans }} over {% trans %}text{% endtrans %}
  • Use the yaml file format.
  • Use the most readable structure: nesting vs flat

    app.test.key: "abc"
    app.test.key2: "def"
    
    # vs
    
    app:
        test:
            key: "abc"
            key2: "def"

Translation keys are named with the following rules:

Component

Domain

Structure

Comments

Forms

forms

entity.field.attribute

Examples:

  • locale.name.label
  • locale.name.help
  • locale.name.placeholder

Invalid Data in Forms

validators

(see validation errors)

Validation errors

validators

entity.field.constraint constraint.label

Examples:

  • locale.name.not_blank
  • locale.name.length.max
  • slug.invalid_format

Backend (Mayd only)

backend

(no restrictions)

Examples:

  • homepage
  • profile.edit

other

messages

(no restrictions)

Use appropriate prefixes if parts of the app are separated from the rest. For example: Mayd uses crud for the translations in the CRUD manager.

If you are building a reusable bundle or encounter duplicate keys, you can qualify the entity part with a custom prefix.

Examples:

  • mayd.locale.name.help
  • customer.client.locale.name.help

Templates

  • Don’t use the @Template annotation.
  • Naming convention is lower kebab-case: for example @MyBundle/main-navigation/layout-left.html.twig.

SVG

  • If you need to add CSS classes to some parts of your SVG to colorize and style them, the following class names are the ones to use:

CSS Property/SVG Attribute

Class name

fill

_f

stroke

_s

As of Samos v1.5 there is a color-svg() mixin available that uses these classes, to simplify the task of coloring an SVG.

npm Packages

  • Use np for publishing modules.
  • Use the BSD-3-Clause license.
  • Set the author to Becklyn Studios <hello@becklyn.com>.
  • Publish a version above 1.0.0 as soon as possible, try to avoid lingering in the 0.x version range for too long.
  • Publish as few files as possible, check the package with npm pack --dry-run.