Workflow
Our workflow is mostly based on the guidelines given at se-education.org/guides. This page points to the relevant parts of those guides and provide additional details specific to MarkBind.
To submit a PR, follow this guide, but note the following:
The sections below has more information about various stages of submitting a PR.
Use JavaScript ES6 features if possible for better performance, e.g. Promise instead of callback.
Do note our style guides.
Do set up your IDE debugger! We provide several sample configurations for WebStorm and VS Code.
When new PRs are merged into the master
branch, your master
branch will be out of sync with the main repository. One way to update your branches to branch from the latest master
is as follows:
Go to your fork on GitHub and click 'Sync fork' to update your remote master
branch
Checkout and sync your local master
(the name of your local branch that tracks the remote master
) branch with git checkout master && git pull
Checkout your feature branch and rebase the branch with git rebase master
or merge master
into the branch with git merge master
Fix any merge conflicts (if applicable)
You may want to use a tool like GitTown to speed up the process.
Some of our backend code files in packages/core
are written in TypeScript, and you will need to compile those into JavaScript for local execution with our command-line module packages/cli
.
You can run npm run build:backend
in the root directory to compile the files, but in some cases, it might be tedious to manually execute the command many times. We recommend you to either:
Run npm run dev
in the root directory. (Recommended for TypeScript migration)
This command starts the compiler's file watcher which will rebuild the relavant files when file changes are detected.
Configure your IDE to perform automatic compilation on file change/save. (Recommended for general development)
Refer to your IDE's guides to set this up. For instance, here are the guides for WebStorm and Visual Studio Code.
We update the frontend markbind.min.js
and markbind.min.css
bundles during release only, and not in pull requests.
Hence, if you need to view the latest frontend changes (relating to packages/core-web
or packages/vue-components
), you can either:
markbind serve -d
(with any other applicable options). (recommended)npm run build:web
in the root directory, which builds the above bundles,
then run your markbind-cli command of choice.Our test script does the following:
.ts
, .js
, .vue
) and stylesheets (.css
) for any style errors using ESLint and StyleLint.packages/cli/test/functional/testSites.js
.expected
directory.To run the test script, use: npm run test
If you only want to run tests for one of the packages (packages/*
), simply switch into the appropriate directory and use npm run test
as well!
Our unit tests perform fast, stable, and comprehensive checks on important behaviors of our classes and functions. Some existing tests can be found in the packages/cli/test/unit
and packages/core/test/unit
directory. Where appropriate, unit tests should be added/modified to account for any new/changed functionality.
Whether you are adding a new feature, updating existing features or fixing bugs, make sure to update the source test files (test sites, snapshots) to reflect the changes.
After which, you can update the with: npm run updatetest
You should always check that the generated output is correct before committing any changes to the test sites.
Note that some binary files such as images (e.g. inline-output.png
) or fonts (e.g. material-icons-outlined.woff
) could show up
as uncommitted changes due to the way they are generated. If you are not directly modifying those files in your PR, you should discard those changes and do not commit them.
Here are the steps to solve merge conflicts in expected test files:
git checkout [BRANCH NAME]
git merge master
npm run updatetest
to generate the latest test files.When adding new features, you should also add new site content into an existing test site or create a new test site to demonstrate the new feature. This is to ensure that your feature can be tested by building that test site.
To add a page to an existing test site, for this example, to test_site
:
Add a new test page, e.g., newTestPage.md
, containing a demonstration of the new feature.
Open the site.json
corresponding to the test site, i.e. packages/cli/test/functional/test_site/site.json
To include the new page, i.e. newTestPage.md
, add it to the pages
array.
"pages": [
{
"src": "index.md",
"title": "Hello World",
"frontmatter": {
"frontmatterOverrideProperty": "Overridden by frontmatter override",
"globalAndFrontmatterOverrideProperty": "Overridden by frontmatter override"
}
},
...
{
"src": "testLayouts.md",
"title": "Hello World"
},
{,
"src": "newTestPage.md",
"title": [some title you see fit]
},
...
Update the tests using npm run updatetest
.
If creating a new test site instead, the directory name of the new test site should be added to packages/cli/test/functional/testSites.js
file.
We do not commit the generated plantuml images in our test_site
to avoid non-related file changes after npm run updatetest
.
The existing list of images to be ignored is maintained in packages/cli/test/functional/testSites.js
and .gitignore
.
They should be updated accordingly if you are making changes to the plantuml content in our test_site
.
When making changes to the Vue components in packages/vue-components
, you should add new snapshot tests or adapt existing ones as appropriate.
Once you're done, be sure to run the updatetest
script mentioned above!
In MarkBind, we use tags to differentiate between links in the developer guide referring to the user guide versus links in the user guide referring to the developer guide. Note that intra-site links within either guides need not have tags.
MarkBind's documentation currently has 3 tags:
environment--combined
for deploying the User Guide and Developer Guide togetherenvironment--ug
for deployed User Guideenvironment--dg
for deployed Developer GuideTo ensure that correct links are created, use tags with the links to selectively filter the correct link to be rendered for the right environment. When both the User Guide and the Developer Guide are deployed together, they have access to the files from each other, allowing the relative link to work. However, when they are deployed individually, this is not the case. Using absolute links creates the same effect as the relative link without having to have access to the files from the other guide.
LINK:
[Link Title](/userGuide/newPage.html)
REPLACED WITH:
<a tags="environment--combined" href="/userGuide/newPage.html">Link Title</a>
<a tags="environment--dg" href="https://markbind.org/userGuide/newPage.html">Link Title</a>
LINK:
[Link Title](/devGuide/newPage.html)
REPLACED WITH:
<a tags="environment--combined" href="/devGuide/newPage.html">Link Title</a>
<a tags="environment--ug" href="https://markbind.org/devdocs/devGuide/newPage.html">Link Title</a>
We follow our style guides. Using a linter will help check and fix some of the code style errors in your code. It will save time for both you and your code reviewer. The linting tool we use is ESLint and StyleLint. Here is a gist with an explanation of the ESLint rules chosen in markbind-cli.
Before making a commit or pull request, you should lint your code by running the following commands from the root of your project:
eslint path/to/specificfile.js
npm run lint
It is also possible to auto-fix some (not all) style errors, using npm run lintfix
.
ESLint has integrations with popular editors. They offer features such as "fix errors on save", which will make development smoother.
We have three git hooks in our project. We use pre-commit to manage our git hooks.
The pre-commit scripts are located in ./pre-commit/pre-commit-scripts
and the config is found in ./pre-commit-config.yaml
.
To skip running the pre-commit hook or pre-push hook, you can use the --no-verify flag (e.g. git push --no-verify origin fork_branch).
post-checkout
: When you checkout to another branch, this hook will run clean and build the backend.pre-commit
: This hook will run clean, build the backend, and run lintfix on all the files.pre-push
: This hook will run clean, build the backend, and run all the test cases.As mentioned in the setting up page, MarkBind uses lerna to manage the dependencies of its various packages.
Add your dependency into the appropriate package.json
file inside packages/*
. If this is a development dependency to be used across all packages (e.g. ESLint), add it the the root package.json
.
Then, simply rerun the npm run setup
command to update the package-lock.json
files.
The safest way is to first remove the particular dependency entry from the package.json
file of the respective directory. Then, run npm run setup
in the root directory to clean up the local dependencies and update the package-lock.json
file.
First, follow the instruction to delete the dependency. Then, follow the instruction to add the latest dependency back. Also, when updating dependencies, ensure that it is updated in all packages using that dependency.
Dependency updates are not trivial, and can be the source of subtle bugs. You should always check the respective dependency changelogs before doing so!
There are a few ways to incorporate external packages into MarkBind, each with its pros and cons. The following table shows some of the common trade-offs:
Approach | Pros | Cons |
---|---|---|
Installing |
|
|
Forking |
|
|
Patching |
|
|
As the choice is highly dependent on context and details of the implementation, below are some additional questions to ask before proceeding:
Find out more about the key external libraries used in MarkBind from the project structure section. Also, the rationales behind most existing patches are documented in their respective files, read them (and their respective PRs/issues) for more context!
PlantUML is a third-party library used by MarkBind to create UML diagrams. MarkBind runs the PlantUML JAR file found in packages/core/src/plugins/default
when building the site to generate the diagrams.
To update PlantUML to a newer version:
plantuml.jar
(if required), and replace the existing JAR file located in packages/core/src/plugins/default
./userGuide/components/imagesAndDiagrams.html
.As Bootswatch is built on Bootstrap, ensure that the versions of both are in sync to avoid unexpected differences in styling behavior between default and other themes. Both are currently using version 5.1.3.