Verified Commit 3a525bd1 authored by Lukas Wiest's avatar Lukas Wiest 🚂
Browse files

refactor(docs): dev-guide: write workflow

parent db2f220f
Pipeline #1382 passed with stages
in 1 minute and 24 seconds
# Workflow
This project is maintained in a GitLab repository,
hosted on the [M4Lab's][m4lab] [Transfer-Portal][tr-portal] [GitLab instance][tr-gitlab].
Source code for the maven Java library and the markdown docs are managed together in a [single repository][lib-repo-home].
This page tells you for the different parts of this project,
how to do it.
The following applies project wide:
- language is english: code, comments, documentation, tickets, discussion, ...
## Git/GitLab
!!! danger "disclaimer"
There are a few rules any developer HAS TO follow,
in order to get any chance his merge-requests will be accepted.
This project is managed using Git, hosted on the universities GitLab instance.
### Issues/Merge Requests handling
Project management happens in the GitLab repositories issue board.
First of all, make sure for everything you do a ticket exists.
Extending this, also check regularly your tickets are:
- assigned to you
- are in the correct column
There are three columns as of writing this documentation: `To Do`, `Doing` and `review`.
Planning something, a new ticket get's created and placed into the `To Do` column.
If you start to work on this ticket
- move it to `Doing`
- create a new feature branch from the master
- named like: `<ticket-id>-<some-descriptive-name>`
- push the new branch
- create a new merge request
- title starting with `wip: `
- description containing `closes #<ticket-id>`
- assign it to you (even if you're not able to merge)
- start working
After implementing your change
- move your ticket to `review` column
- change your merge requests labels: remove `Doing` and add `review`
- change assignee to someone to review your work
### Branch Names
Branches should always start with the number of the related ticket, followed by a dash.
This way the branch get's automatically shown in the ticket.
### Committing
!!! tip "golden rules"
- __many small__ > ~~few big~~ commits
- unrelated changes in separate commit
We encourage everyone to make heavy use of `git status` and `git diff`.
Please always check before committing, what exactly you have changed.
What we won't accept:
- whole file content removed and added back
This most likely happens if you make great use of auto format,
messing everything up.
Another one error source is something changed line endings.
- empty lines containing spaces, or trailing spaces on line end (without technical reason)
No big deal to fix, but time waste if we have to block your MR because of this.
- multiple changes in one commit, that have nothing to do with each other
Great you have fixed a typo in a comment at the other end of the file.
What do you think happens, if five people fix the same typo in their commits?
We would have four merge conflicts, needing manual work to fix this mess.
So create a new ticket for what you found,
instead of just doing it as it doesn't hurt.
It hurts, trust me.
- commit messages not following conventional commits specification
!!! tip "view diff of not yet tracked files"
If you want to check a new file for flaws, sure `git diff` doesn't show anything.
But you can add the file and before committing check with `git diff --cached`.
!!! tip "add only parts of changes in a file"
As we want to have more small commits, than one single big one,
it can be useful to split your changes into multiple commits,
even inside the same file.
You can use `git add -p [path|file]`.
This allows you to exactly decide which lines of your changes should be staged
, before committing.
#### Commit Messages
We use the [conventional commits][conv-comm] specification in this repository,
to auto generate a changelog with [conventional-changelog][conv-change].
### Protected Branches/Tags
The repository has the master branch and release tags (format `^[0-9]+\.[0-9]+\.[0-9]+$`)
protected to project maintainers.
### Branching-Model
We use a branch per feature based branching model.
Base and target to merge is always latest `master`.
## Java Development
First step before changing the source code,
would be to check if there's something going on yet,
or this topic possibly was discussed yet and abandoned for some reason.
For this, check the [defined GitLab workflow](#gitgitlab).
This library is a maven project.
In order to contribute to it,
make sure your machine is setup according to the [setup guide][setup-guide].
### Change an existing functionality
- check with the [source structure below](#source-code-structure),
where to find the part you want to change.
- make your changes
- make sure all unittests still pass
- commit your changes following the Git/GitLab workflow defined.
### Add integration for new system
- familiarize with the [code structure](#source-code-structure)
- create a new package under `de.hftstuttgart.unifiedticketing.systems`,
identifying the new system
- prepare to implement all abstract classes from the `core` package
- class names have to be the same as the `core` ones,
prefixed with the identifier you named your package after
- create unittests for the planned integration,
either by putting a `fail();` into each testmethod,
or really writing tests first for TDD
- commit & push this skeleton-like state
- create WIP merge-request
- implement
### Source code structure
After cloning the repository,
you'll have to open/import an existing maven project in your IDE of choice.
There WILL NOT be any configuration files for a specific IDE committed into the code.
In regards to the maven project parts,
only the `pom.xml` and the contents under `/src` are committed.
The main package for everything of this library is `de.hftstuttgart.unifiedticketing`.
Beneath it is split into three sub-packages:
| subpackage | content |
| :----------- | :------------------------------------------------------------------------- |
| `core` | root classes defining lib core, generic public interface |
| `exceptions` | library own exceptions |
| `systems` | subpackage per system integration, implementation of abstract core-classes |
__core:__
The majority of the classes are abstract ones.
They define the generic interface available to the user of this lib.
Logic identical for all system integrations are found in these classes.
Only few methods are really declared abstract,
in most cases it's the part calling the external system.
__exceptions:__
The library defines its own exceptions, based on `RuntimeException`.
If you throw any exception,
__only__ use exceptions from this package,
never anything else.
If you miss an exception you'd like to throw,
add a new one that extends `UnifiedTicketingException`.
__systems:__
Each system that's integrated into this lib,
will have a sub-package under `de.hftstuttgart.unifiedticketing.systems`.
In this very own package every abstract class from the `core`-package has to be implemented.
Apart from that,
every system can define as many helper classes
or additional sub-packages.
### Unittests
The logical code is structured under `/src/main/java`.
For unittests the same package structure is created under `/src/test/java`.
Tests are written using the `jupiter-engine` from JUnit5,
combined with `Mockito3`.
- test-classes are named identical to the class under test,
suffixed with `Test`
- test-classes have to be in the same package than the class under test
What has to be tested:
- constructors
- getters/setters
- calculations/transformations/...
- fluent-api to return the same instance
- serializing request data before request
- failing web-request
- successful web-request & deserializing of received data
!!! warning "testing external resources"
All tests _have to_ run offline.
To test external resources,
e.g. a web-request,
use Mockito to block the code under test to really access the external resource
and transparently return your mock answer expected for the assertions following.
??? tip "test abstract classes"
To test non-abstract code of abstract classes,
you can instantiate a mock of it through Mockito,
set to call the real methods:
```java
instance = mock(ClassUnderTest.class,
withSettings().useConstructor().defaultAnswer(CALLS_REAL_METHODS));
```
## Documentation
Documentation for the project is done entirely in Markdown
and rendered through MkDocs to a Website.
The repository global `README.md` just points to the documentation root,
which is `/docs/index.md`.
The same applies for the `CONTRIBUTING.md`.
`CHANGELOG.md` and `LICENSE.md` are kept with content in project root,
they are linked with a relative soft-link into the documentation folder.
Files related to the documentation:
| path | description |
| :----------------- | :---------------------------------------------- |
| `mkdocs.yml` | configuration file for mkdocs |
| `requirements.txt` | needed pypi packages to pass to pip for install |
| `/docs/**/*` | documentation files |
| `/docs/index.md` | Pages root |
With the aim to give the documentation an appealing appearance,
additional to the default markdown specification,
a few extensions are enabled in the mkdocs config.
Please have a look at them and make use of,
where it seems adequate.
Reference for them can be found in the [MkDocs-Material site][mat-mkdocs-ext-ref].
To make any kind of diagram, sketch or similar,
use [PlantUML][puml].
You have to surround the PlantUML code with code fences,
marked as `plantuml` as language identifier.
Then they will be rendered into an svg on pages creation.
!!! bug
I tried to put this into an collapsed example admonition,
but the PlantUML diagram get's always placed outside the admonition.
Same applies for a tabbed environment.
Example:
__code:__
``````
```plantuml
queue "write\nmarkdown" as write
queue "commit/push/\nmerge changes" as update
queue "pipeline\ntriggered" as cicd
queue "MkDocs\nMaterial" as MkDocsMat
queue "transpiled HTML\nonline" as deployed
write -right-> update
update -right-> cicd
cicd -right-> MkDocsMat
MkDocsMat -right-> deployed
```
``````
__result:__
```plantuml
queue "write\nmarkdown" as write
queue "commit/push/\nmerge changes" as update
queue "pipeline\ntriggered" as cicd
queue "MkDocs\nMaterial" as MkDocsMat
queue "transpiled HTML\nonline" as deployed
write -right-> update
update -right-> cicd
cicd -right-> MkDocsMat
MkDocsMat -right-> deployed
```
## Schedule a release
For releases this project uses [standard-version][std-ver].
This generates an automatic changelog based on the commits
and tags it.
The version of the library has three numbers
and has to follow the [semantic-version][semver] scheme.
Tags marking a release have the format `^[0-9]+\.[0-9]+\.[0-9]+$`.
Pushing these tags is restricted in the GitLab Repo settings
for maintainers only.
Pushing a release tag triggers the CI/CD release pipeline for the maven project.
## CI/CD
This project uses GitLab-CI pipelines for
- publishing the maven library to the repository own package registry
- deploying this pages documentation
These pipelines are defined in several files:
| file | content |
| :---------------------- | :------------------------------------------------------------ |
| `.gitlab-ci.yml` | root file, stages definition, include of other pipeline parts |
| `.gitlab-ci-maven.yml` | jobs regarding java library |
| `.gitlab-ci-mkdocs.yml` | jobs regarding pages documentation |
pipeline graph overview:
```plantuml
rectangle "compile" as stageCompile {
' maven
agent "maven:compile" as mvnCompile
' mkdocs
agent "mkdocs:compile" as mkdocsCompile
}
rectangle "test" as stageTest {
' maven
agent "maven:test" as mvnTest
' mkdocs
agent "none" as mkdocsTest
}
rectangle "deploy" as stageDeploy {
' maven
agent "maven:publish:master" as mvnPublMaster
agent "maven:publish:release" as mvnPublRelease
label "get's deployed with\n'devel' as version" as labelMvnPublMaster
label "get's deployed\nwith release version" as labelMvnPublRelease
' mkdocs
agent "mkdocs:bundle" as mkdocsBundle
agent "mkdocs:deploy" as mkdocsDeploy
label "creates tar archive as\ndownloadable job artifact" as labelMkdocsBundle
label "only triggered\non master branch" as labelMkdocsDeploy
}
' maven pipeline connections
mvnCompile -right-> mvnTest
mvnTest -right-> mvnPublMaster
mvnTest -right-> mvnPublRelease
mvnPublMaster -right- labelMvnPublMaster
mvnPublRelease -right- labelMvnPublRelease
' mkdocs pipeline connections
mkdocsCompile -right-> mkdocsTest
mkdocsTest -right-> mkdocsBundle
mkdocsTest -right-> mkdocsDeploy
mkdocsBundle -right- labelMkdocsBundle
mkdocsDeploy -right- labelMkdocsDeploy
' compile stage keep in place
mvnCompile --[hidden]down- mkdocsCompile
' test stage keep in place
mvnTest --[hidden]down-mkdocsTest
' deploy stage keep in place
mvnPublMaster -[hidden]down- mvnPublRelease
mvnPublRelease -[hidden]down- mkdocsBundle
mkdocsBundle -[hidden]down- mkdocsDeploy
```
These jobs are defined with the `needs` keyword,
to make them only depend on exactly the needed previous jobs.
This makes it possible to run docs and library pipelines in parallel,
without waiting that all jobs of a stage must have finished before entering the next stage.
With the `only` keyword the trigger of these pipelines is optimized,
to only run if necessary.
In general the final deployment jobs have configurations to run only on the secured branches/tags.
Additionally all jobs are configured to only run,
if changes on related files of this pipeline were made.
[conv-comm]: https://www.conventionalcommits.org/en/v1.0.0/
[conv-change]: https://github.com/conventional-changelog/conventional-changelog
[lib-repo-home]: https://transfer.hft-stuttgart.de/gitlab/9Lukas5/unified-ticketing/
[m4lab]: https://www.hft-stuttgart.de/forschung/innovative-hochschule-m4-lab
[mat-mkdocs-ext-ref]: https://squidfunk.github.io/mkdocs-material/reference/abbreviations/
[puml]: https://plantuml.com/
[setup-guide]: /404.html
[semver]: https://semver.org/
[std-ver]: https://github.com/conventional-changelog/standard-version
[tr-gitlab]: https://transfer.hft-stuttgart.de/gitlab/explore/projects
[tr-portal]: https://transfer.hft-stuttgart.de/
......@@ -30,6 +30,7 @@ nav:
- Developers Guide:
- Index: 'developers-guide/index.md'
- Styleguide: 'developers-guide/styleguide.md'
- Workflow: 'developers-guide/workflow.md'
theme:
features:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment