# Websites and Apps Team
## Suggestions for Good Software Development Practices
These are some suggestions, originally authored by [grahamwhiteuk](https://fedoraproject.org/wiki/User:Grahamwhiteuk), that are designed to help introduce best practice and some rigour to the websites and apps team's development repositories and workflows.
The suggestions are broken into 3 broad categories, as outlined below:
- [Developing Code](#Developing-Code)
- [Project Tracking](#Project-Tracking)
- [DevOps](#DevOps)
Each category is split into sections that are deliberately focused on atomic actions that can be taken. Noting that a lot of what is suggested here is often very personal to each developer often with strong opinions. Thus, breaking things down helps to focus any discussions to a specific and limited area of software development. What I write here should be considered as a starting point, never fixed in stone, that can be iterated over time as the preferences of the development team change.
### Developing Code
These items are focused aronud the specific act of developing code and setting up one's development environment. I will focus on JavaScript/TypeScript development environments as my understanding of what is being done in Web Sites and Apps is mostly Next/VueJS based front end development. I can offer some alternative suggestions if there's a need for other languages such as using Python on the back end for APIs.
Apologies, I will focus on GitHub rather than GitLab as that's what I'm much more familiar with but hopefully GitLab will have broadly equivalent functionality.
#### Template Repositories
Create one or more [template repositories](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository). Any new repository should be started from a template. The template will be used to enforce good practices as outlined in other sections, such as:
- have an informative readme with a standard set of sections, at least consisting of the regular "install / run / build / deploy" steps but probably a lot more besides
- a basic package.json including some standard devdependencies
- a set of [issue templates](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/about-issue-and-pull-request-templates) that require people to write good [bug|feature] requests
- a pull request template that enforces good pull request information and would likely include a set of reminders/checks for the PR author (such as whether they've run tests, does their code conform to the code style guidelines, has it been linted, etc)
- contributing guidelines in a CONTRIBUTING.md file
- anything else you want to make sure is always included in new repositories
#### Branching Strategy
Adopt a [good branching strategy](https://gist.github.com/digitaljhelms/4287848).
For example:
* Stable Branch: accepts merges from main and hot-fixes
* holds the current deployed version
* ideally set up with a continuous integration pipeline to automatically update our deployment
* Main Branch: accepts merges from development branches and hot-fixes
* holds the current development version
* should always be stable and working
* has not yet been deployed
* Development Branches: branched from main
* development to take place in feature branches (features/enhancements, bug fixes)
* likely to contain partially implemented code, may not be working and might be failing tests
* Hot-Fix Branches: branched from stable
* quick bug fixes we need to make to the deployed version that will bypass the main branch to deployment
* need to assess whether each hot-fix also applies to the main branch
* aim is to avoid using this type of branch where we can
In addition to the above branching strategy we should aim to use rebasing where possible rather than merging to keep a clean commit history.
#### Code Review
Use the following branch protection rules for “main” and “stable” branches (hopefully GitLab has equivalents)
* Require pull request reviews before merging: ensures all code is reviewed before being merged
* Dismiss stale pull request approvals when new commits are pushed: ensures previous pull request approvals are revoked if new commits are added
* Require status checks to pass before merging: we will need to define which status checks we would like
* Require branches to be up to date before merging
* Include administrators (enforce all configured restrictions for administrators)
* Disallow force pushes for all users with push access
* Disallow users with push access to delete matching branches
Set the merge button to:
* Automatically delete head branches
Optional (to be decided on a per project basis):
* Define owners for various parts of the code base, specified in the CODEOWNERS file
* Restrict who can dismiss pull request reviews, need to define who takes this role for the project
#### Commit Messages
Lint commit messages as conforming to the standards set out by [conventional commits](https://www.conventionalcommits.org)
* This will be configured as a [git pre-commit hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
* Linting to be standardised with a DevDependency upon [@commitlint/config-conventional](https://www.npmjs.com/package/@commitlint/config-conventional)
Commit messages:
* Should be atomic
* Should contain an issue number where appropriate
* PRs have a strong preference to cite an issue number or have their commits contain issue numbers
* Should conform to a provided template (look out a good [example](https://gist.github.com/lisawolderiksen/a7b99d94c92c6671181611be1641c733) of a template and modify to the needs/preferences of this team)
* The template will include an issue number
* Commits messages will not be linted on the issue number field i.e. we encourage the behaviour of adding issues to commit messages but this is not enforced.
#### Code Linting
We use code linting:
* This will be configured as a pre-commit hook
* Adopt eslint as a DevDependency
* The only acceptable lint ignores should be
* build directories (e.g. build, dist)
* module/environment directories (e.g. node_modules)
* markdown files
* Encourage the use of linting IDEs (e.g. vscode)
#### Code Formatting
We should use automatic code formatting:
* This will be configured as a pre-commit hook
* Adopt prettier with the following configuration in .prettierrc
```
{
"arrowParens": "always",
"singleQuote": true,
"trailingComma": "none",
"semi": false,
"printWidth": ?
}
```
Note: the above is a suggested starting point, it's worth having a discussion with the main people writing code as to what the preferred settings should be (particularly for line length).
* Encourage the use of “format on save” in your IDE
#### Commit Hooks
We should use pre-commit hooks:
* Adopt [husky](https://github.com/typicode/husky)
* Must have prepare script set to "husky install" in package.json
* Hooks will be configured for:
* commit messages (conventional commits)
* code linting (flake8 or eslint)
* automatic code formatting (black or prettier)
* detect secrets
* running tests
* any others???
* These hooks will also be configured as pre-receive hooks and thus enforced on the Git server and must be passed before PRs can be accepted
#### Environment Variables
Adopt [dotenv-safe](https://www.npmjs.com/package/dotenv-safe) as a DevDependency in package.json. This is an alternative to the standard dotenv library with the addition that a .env.example file must be maintained that documents the required .env variables.
We need to define how and where secrets are kept to make them accessible to the administrators of the websites and apps team.
#### Logging
Adopt a standard logging library and set out standards for which logging levels should be used at various points in the code e.g. [vuejs3-logger](https://www.npmjs.com/package/vuejs3-logger)
#### Testing
Standardise on a particular [testing framework](https://vuejs.org/guide/scaling-up/testing.html) and ensure tests are written. VueJS recommends the use of [Vitest](https://vitest.dev/)
### Project Tracking
It looks like the team are currently using a KanBan board for GitLab issue management. I would definitely encourage this.
It looks as though you have 2 KanBan boards that have swim lanes set up as follows:
1. Project Organization board:
* Todo: tasks that need to be assigned
* Doing: tasks that are currently in progress
* Testing: components and pages that are built but being tested and optimized
* Closed
2. Priority Board:
* Open
* Low: issues that are of value but not essential to the success of the overall project to complete.
* Medium: issues that are of moderate importance to the success of the overall project to complete.
* High: issues that are of high importance to the success of the overall project to complete.
* Closed
I would find the approach of having 2 boards confusing. Most of your issues are not prioritised and thus reduces the effectiveness of your 2nd board anyway so I would perhaps focus on a single board and if you need to prioritise tasks as low|medium|high then use tags/labels.
I would typically set up a board like this:
* Epics - Group issues into epics to easily track long-term goals.
* New Issues - Issues to be reviewed and estimated before being added to the Backlog
* On Hold / Icebox - Issues that are still open and that we want to keep track of but for a variety of reasons are put on hold for a while
* Backlog - New issues are moved here once they have been fleshed out and are ready to be worked on
* Sprint Backlog - An ordered list of issues prioritised for the current sprint
* In Progress - Issues which now assigned and are actively being worked on
* Review/QA - Issues which are code complete and ready to be reviewed, pending feedback
* Closed - Issues where all the acceptance criteria has been met with all work, testing and feedback completed
Looking at the way GitLab boards work, you may not need a swim lane for Epics since the "Group by Epics" view looks very useful instead.
If you want to organise around sprints (which may be a bit too ambitious for a project containing volunteers) then I would recommend having sprint planning meetings and retrospective meetings. If you don't want to have sprints then perhaps break work down into relatively granular milestones but still hold planning meetings and retrospective meetings for each of your granular milestones. The retrospective meetings should evaluate success, recommend any changes and queue those up for future work items. The planning meetings should consider:
* how are new tasks added
* how are tasks sized (use the "weight" feature in your board?) and assigned
If you adopt the "weight" feature of the GitLab boards, this is a suggested starting point for sizing tasks:
* 1 - A trivial issue that requires little effort and has no technical complexity
* 2 - An issue with requires some more effort and may have a little technical complexity
* 3 - An issue with a medium amount of effort and a small amount of technical complexity
* 5 - An issue which requires large effort and is more technically involved
* 8 - A large issue which requires substantial effort and has a large amount of technical complexity
* 13+ - Any issue which requires more effort and is more technically complex than the others suggests it needs to be broken down into smaller issues which are sized accordingly
Ideally your epics or milestones would reflect the user stories developed during the design phase of the work. Then you work in a meeting between the design team and technical team to translate those into epics and tasks on the kanban board.
#### Recommendations
With all of the above said and in mind, for this group I would consider taking the following actions:
1. Evaluate your GitLab board swim lane structure
* Is it doing what you need? Could it be improved?
* Does everyone understand the purpose of each of the swim lanes?
* Is there a defined process for how issues move across the board? Does everyone know what this is?
2. Consider whether you want to use "weight" on the board for sizing tasks
* If you do, make sure everyone has a consistent definition for sizes
* The advantage you get is to consider the complexity of the task (by weight) when prioritising your backlog
* The disadvantage is that it takes some time and brain power to consider this in advance
3. Split the Wednesday meeting into 3 distinct sections (in this order):
* Section 1: retrospective, focus on what has been done since the last meeting
* Section 2: planning, focus on what you'll be doing for the forthcoming week
* Section 3: general, have any other technical/working discussions
4. Drive the Wednesday meeting using the KanBan board
* The board should be open and screen shared with someone updating the issues with comments
* This provides a much more effective status against each issue than taking minutes in HackMD
* It's probably also useful to take minutes as well though :-)
5. Ensure that all tasks are part of some wider epic or milestone
* Otherwise, why is that task being done?
* Use either epics or milestones to document the user stories from the design
### DevOps
Before I write too much here, we should probably have a chat about how things are being run at the moment. Sections for consideration here are:
- Deployment location
- CI/CD tooling (e.g. Travis vs Jenkins vs Tekton, etc)
- Asset reuse
- discuss the use of modular components that we've written
- how are components reused across repositories
- where are modules stored and how can they be accessed