├── .codespellrc ├── .editorconfig ├── .gitignore ├── .gitlab-ci.yml ├── .gitlint ├── .gitmodules ├── .mailmap ├── .markdownlint.yml ├── .markdownlintignore ├── .pre-commit-config.yaml ├── .releaserc.yaml ├── .shellcheckrc ├── .vscode └── extensions.json ├── .yamllint.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cspell.config.yaml ├── images ├── workflow-feature.png ├── workflow-fix.png ├── workflow-full.png ├── workflow-release.png └── workflow.drawio ├── requirements.txt ├── scripts ├── bootstrap ├── pre-commit ├── pre-push ├── setup ├── test └── update ├── templates ├── MIT-LICENSE ├── NO-LICENSE └── README.md └── tests ├── bootstrap.bats ├── fast.set ├── full.set ├── nightly.set ├── pre-commit.bats ├── pre-push.bats ├── reduced.set ├── setup.bats ├── test.bats └── update.bats /.codespellrc: -------------------------------------------------------------------------------- 1 | [codespell] 2 | skip = CHANGELOG.md,images/* 3 | count = 4 | quiet-level = 3 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | indent_size = 4 4 | end_of_line = lf 5 | charset = utf-8 6 | 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [.git*] 11 | indent_size = tab 12 | indent_style = tab 13 | 14 | [{**.*sh,**.bats}] 15 | shell_variant = bash 16 | binary_next_line = true # like shftm -bn 17 | switch_case_indent = true # like shftm -ci 18 | space_redirects = true # like shftm -sr 19 | keep_padding = false # like shftm -kp 20 | 21 | [**.bats] 22 | shell_variant = bats 23 | 24 | [{**.md,**.json,**.yml,**.yaml}] 25 | indent_size = 2 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache/ 2 | .venv/ 3 | .envrc 4 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # cSpell:ignore urllib unprotect interruptible 3 | stages: 4 | - validate 5 | - release 6 | 7 | default: 8 | image: alpine:latest 9 | before_script: &default_before_script 10 | - apk -U upgrade 11 | 12 | variables: 13 | GIT_SUBMODULE_STRATEGY: recursive 14 | 15 | .lint: 16 | stage: validate 17 | variables: 18 | PIP_CACHE_DIR: $CI_PROJECT_DIR/.cache/pip 19 | PRE_COMMIT_HOME: $CI_PROJECT_DIR/.cache/pre-commit 20 | GITLAB_PRIVATE_TOKEN: $GL_TOKEN 21 | # Skip protect-first-parent pre-commit hook until `[ERROR] caught error 1 on line 69 of ...: FIRST_PARENT="$(git show-ref -s "${BASE}")"` is fixed 22 | SKIP: check-hooks-apply,protect-first-parent 23 | before_script: 24 | - *default_before_script 25 | - apk --no-cache add bash git go grep npm py-pip python3-dev shellcheck shfmt 26 | - python3 -m venv .venv 27 | - source .venv/bin/activate 28 | - pip install -r requirements.txt 29 | - npm install -g markdownlint-cli 30 | script: 31 | - pre-commit run -a --hook-stage manual 32 | cache: 33 | - key: default 34 | paths: 35 | - $PIP_CACHE_DIR 36 | unprotect: true 37 | - key: 38 | files: 39 | - requirements.txt 40 | paths: 41 | - .venv 42 | when: always 43 | - key: 44 | files: 45 | - .pre-commit-config.yaml 46 | paths: 47 | - $PRE_COMMIT_HOME 48 | unprotect: true 49 | when: always 50 | interruptible: true 51 | 52 | lint: 53 | extends: [.lint] 54 | variables: 55 | SKIP: check-hooks-apply,protect-first-parent,anti-todo 56 | rules: 57 | - if: $CI_PIPELINE_SOURCE != 'merge_request_event' 58 | 59 | lint-merge-request: 60 | extends: [.lint] 61 | rules: 62 | - if: $CI_PIPELINE_SOURCE == 'merge_request_event' 63 | 64 | .test: 65 | stage: validate 66 | 67 | .test-alpine: 68 | extends: [.test] 69 | before_script: 70 | - *default_before_script 71 | - apk --no-cache add bats git 72 | 73 | .test-ubuntu: 74 | extends: [.test] 75 | image: ubuntu:latest 76 | before_script: 77 | - apt-get update && apt-get upgrade -y 78 | - apt-get install -y bats git 79 | 80 | .test-full: 81 | script: 82 | - scripts/test tests/full.set 83 | interruptible: true 84 | rules: 85 | - if: $CI_PIPELINE_SOURCE != "schedule" 86 | 87 | .test-nightly: 88 | script: 89 | - scripts/test tests/nightly.set 90 | rules: 91 | - if: $CI_PIPELINE_SOURCE == "schedule" 92 | 93 | test-alpine-full: 94 | extends: [.test-alpine, .test-full] 95 | 96 | test-alpine-nightly: 97 | extends: [.test-alpine, .test-nightly] 98 | 99 | test-ubuntu-full: 100 | extends: [.test-ubuntu, .test-full] 101 | 102 | test-ubuntu-nightly: 103 | extends: [.test-ubuntu, .test-nightly] 104 | 105 | release: 106 | stage: release 107 | image: 108 | name: node:alpine 109 | entrypoint: [""] 110 | before_script: 111 | - *default_before_script 112 | - apk --no-cache add git 113 | - npm install -g semantic-release @semantic-release/gitlab @semantic-release/git @semantic-release/changelog 114 | script: 115 | - npx semantic-release 116 | rules: 117 | - if: $CI_COMMIT_BRANCH =~ /^(((0|[1-9]\d*)\.)(((0|[1-9]\d*|x)\.)?x)|main|next(-major)?|beta|alpha)$/ && $CI_PIPELINE_SOURCE != "schedule" 118 | resource_group: release 119 | -------------------------------------------------------------------------------- /.gitlint: -------------------------------------------------------------------------------- 1 | [general] 2 | ignore=body-is-missing 3 | 4 | contrib=contrib-title-conventional-commits 5 | 6 | [ignore-by-title] 7 | regex=^chore\(release\).*$ 8 | ignore=body-max-line-length 9 | 10 | [title-must-not-contain-word] 11 | words=wip,todo,tbd 12 | 13 | [contrib-title-conventional-commits] 14 | types=build,chore,ci,docs,feat,fix,perf,refactor,style,test 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tests/helpers/bats-assert"] 2 | path = tests/helpers/bats-assert 3 | url = https://github.com/bats-core/bats-assert.git 4 | [submodule "tests/helpers/bats-support"] 5 | path = tests/helpers/bats-support 6 | url = https://github.com/bats-core/bats-support.git 7 | [submodule "tests/helpers/bats-file"] 8 | path = tests/helpers/bats-file 9 | url = https://github.com/bats-core/bats-file.git 10 | [submodule "scripts/shellib"] 11 | path = scripts/shellib 12 | url = https://github.com/xebis/shellib.git 13 | branch = main 14 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Martin Bruzina Martin Bružina 2 | -------------------------------------------------------------------------------- /.markdownlint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | default: true 3 | MD003: 4 | style: atx 5 | MD004: 6 | style: dash 7 | MD013: false 8 | MD035: 9 | style: --- 10 | MD049: 11 | style: underscore 12 | MD050: 13 | style: asterisk 14 | -------------------------------------------------------------------------------- /.markdownlintignore: -------------------------------------------------------------------------------- 1 | CHANGELOG.md 2 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # cSpell:ignore pygrep 3 | default_stages: [commit, manual, merge-commit, push] 4 | repos: 5 | - repo: https://github.com/jorisroovers/gitlint 6 | rev: v0.19.1 7 | hooks: 8 | - id: gitlint 9 | - repo: https://github.com/pre-commit/pre-commit-hooks 10 | rev: v4.5.0 11 | hooks: 12 | - id: check-added-large-files 13 | args: [--maxkb=1024] 14 | - id: check-case-conflict 15 | - id: check-executables-have-shebangs 16 | - id: check-json 17 | - id: check-merge-conflict 18 | - id: check-symlinks 19 | - id: check-vcs-permalinks 20 | - id: destroyed-symlinks 21 | - id: detect-private-key 22 | - id: end-of-file-fixer 23 | exclude: .*\.drawio$ 24 | - id: fix-byte-order-marker 25 | - id: forbid-new-submodules 26 | - id: mixed-line-ending 27 | args: [--fix=lf] 28 | - id: no-commit-to-branch 29 | - id: pretty-format-json 30 | args: [--no-ensure-ascii] 31 | - id: trailing-whitespace 32 | - repo: https://github.com/jumanjihouse/pre-commit-hooks 33 | rev: 3.0.0 34 | hooks: 35 | - id: check-mailmap 36 | - id: forbid-binary 37 | exclude: .*\.png$ 38 | - id: git-check 39 | - id: git-dirty 40 | - id: protect-first-parent 41 | - id: script-must-have-extension 42 | exclude: .*\.bats$ 43 | - id: script-must-not-have-extension 44 | - repo: meta 45 | hooks: 46 | - id: check-hooks-apply 47 | stages: [manual] 48 | - id: check-useless-excludes 49 | - repo: https://github.com/codespell-project/codespell 50 | rev: v2.2.6 51 | hooks: 52 | - id: codespell 53 | - repo: https://github.com/igorshubovych/markdownlint-cli 54 | rev: v0.38.0 55 | hooks: 56 | - id: markdownlint 57 | - repo: https://github.com/adrienverge/yamllint.git 58 | rev: v1.33.0 59 | hooks: 60 | - id: yamllint 61 | args: [--strict] 62 | - repo: https://gitlab.com/devopshq/gitlab-ci-linter 63 | rev: v1.0.6 64 | hooks: 65 | - id: gitlab-ci-linter 66 | args: [--project, xebis/repository-template] 67 | - repo: local 68 | hooks: 69 | - id: anti-todo 70 | name: anti-todo 71 | entry: (?i)#\s*\b(wip|todo|tbd)\b 72 | language: pygrep 73 | types: [text] 74 | stages: [manual] 75 | - id: shfmt 76 | name: shfmt 77 | entry: shfmt -i 4 78 | language: system 79 | types: [shell] 80 | - id: shfmt-bats 81 | name: shfmt-bats 82 | entry: shfmt -ln bats -i 4 83 | language: system 84 | files: .*\.bats$ 85 | - id: shellcheck 86 | name: shellcheck 87 | entry: shellcheck -x -P scripts:scripts/shellib 88 | language: system 89 | types: [shell] 90 | - repo: https://github.com/gitleaks/gitleaks 91 | rev: v8.18.1 92 | hooks: 93 | - id: gitleaks 94 | -------------------------------------------------------------------------------- /.releaserc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | branches: 3 | - +([0-9])?(.{+([0-9]),x}).x 4 | - main 5 | - next 6 | - next-major 7 | - name: beta 8 | prerelease: true 9 | - name: alpha 10 | prerelease: true 11 | plugins: 12 | - "@semantic-release/commit-analyzer" 13 | - "@semantic-release/release-notes-generator" 14 | - "@semantic-release/changelog" 15 | - "@semantic-release/git" 16 | - "@semantic-release/gitlab" 17 | - "@semantic-release/github" 18 | -------------------------------------------------------------------------------- /.shellcheckrc: -------------------------------------------------------------------------------- 1 | external-sources=true 2 | source-path=scripts:scripts/shellib 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "alefragnani.Bookmarks", 4 | "blackmist.LinkCheckMD", 5 | "codezombiech.gitignore", 6 | "DavidAnson.vscode-markdownlint", 7 | "donjayamanne.githistory", 8 | "EditorConfig.EditorConfig", 9 | "foxundermoon.shell-format", 10 | "GitLab.gitlab-workflow", 11 | "Gruntfuggly.todo-tree", 12 | "gurumukhi.selected-lines-count", 13 | "jetmartin.bats", 14 | "mads-hartmann.bash-ide-vscode", 15 | "mhutchie.git-graph", 16 | "mushan.vscode-paste-image", 17 | "nhoizey.gremlins", 18 | "redhat.vscode-yaml", 19 | "SeyyedKhandon.epack", 20 | "SeyyedKhandon.gpack", 21 | "SeyyedKhandon.tpack", 22 | "streetsidesoftware.code-spell-checker", 23 | "timonwong.shellcheck", 24 | "yzhang.markdown-all-in-one", 25 | "znck.grammarly" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /.yamllint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | braces: 6 | min-spaces-inside: 1 7 | max-spaces-inside: 1 8 | comments: 9 | min-spaces-from-content: 1 10 | empty-lines: 11 | max: 1 12 | empty-values: enable 13 | indentation: 14 | spaces: 2 15 | line-length: disable 16 | octal-values: enable 17 | quoted-strings: 18 | required: only-when-needed 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.30.1](https://gitlab.com/xebis/repository-template/compare/v0.30.0...v0.30.1) (2024-1-1) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * gitlab ci linter fails on missing project argument ([27bfbaa](https://gitlab.com/xebis/repository-template/commit/27bfbaa8c875eae38f9258875b934165afd9101c)) 7 | 8 | # [0.30.0](https://gitlab.com/xebis/repository-template/compare/v0.29.0...v0.30.0) (2023-12-9) 9 | 10 | 11 | ### Features 12 | 13 | * remove secrets.sh script ([62b571f](https://gitlab.com/xebis/repository-template/commit/62b571f1daec6a5319001acccefec6c323f0a47b)) 14 | 15 | # [0.29.0](https://gitlab.com/xebis/repository-template/compare/v0.28.0...v0.29.0) (2023-10-14) 16 | 17 | 18 | ### Features 19 | 20 | * extend editorconfig to include all file formats ([c7c9721](https://gitlab.com/xebis/repository-template/commit/c7c97217baeffbf95aac197478e627cbb4b12171)) 21 | 22 | # [0.28.0](https://gitlab.com/xebis/repository-template/compare/v0.27.1...v0.28.0) (2023-06-24) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * foxtrot merges are not prevented ([ef7254c](https://gitlab.com/xebis/repository-template/commit/ef7254c41687f8276aef0e2fb4eec5f675ff5ad4)) 28 | * hooks are run twice during a commit ([0ca75f3](https://gitlab.com/xebis/repository-template/commit/0ca75f34b1552eb754fa488d256ac7a015989856)) 29 | 30 | 31 | ### Features 32 | 33 | * add pre-commit meta hook check-hooks-apply ([f09026c](https://gitlab.com/xebis/repository-template/commit/f09026cd4800e37ab727881fad8360463395aa14)) 34 | * add suggested vscode extensions as vscode recommendations ([1eef470](https://gitlab.com/xebis/repository-template/commit/1eef470d5d8d2b1ff57613be53d61796914a8228)) 35 | * anti-todo hook is run only manually or in a merge request pipeline ([e6f62c9](https://gitlab.com/xebis/repository-template/commit/e6f62c9f8ad37e4514e2a5ff83e12d70f812178f)) 36 | 37 | ## [0.27.1](https://gitlab.com/xebis/repository-template/compare/v0.27.0...v0.27.1) (2023-04-30) 38 | 39 | 40 | ### Bug Fixes 41 | 42 | * execute pre-commit from hook scripts as from the original hooks ([9d2bb21](https://gitlab.com/xebis/repository-template/commit/9d2bb219739e0f2371b7a03236c7de1e5eb0665d)) 43 | * pre-push script shouldn't have hardcoded repository path ([d4ecf0e](https://gitlab.com/xebis/repository-template/commit/d4ecf0e6290bc9792794f145cb08723037657e71)) 44 | 45 | # [0.27.0](https://gitlab.com/xebis/repository-template/compare/v0.26.0...v0.27.0) (2023-04-29) 46 | 47 | 48 | ### Features 49 | 50 | * test sets specified as a file instead of hardcoded lists ([2fb290c](https://gitlab.com/xebis/repository-template/commit/2fb290cc9c50cf5c08ef761eb73e37a11751ce3f)) 51 | 52 | # [0.26.0](https://gitlab.com/xebis/repository-template/compare/v0.25.0...v0.26.0) (2023-04-08) 53 | 54 | 55 | ### Bug Fixes 56 | 57 | * cspell warnings ([fbedcf3](https://gitlab.com/xebis/repository-template/commit/fbedcf384ac813a5cfff3aea9e71464f38abbc07)) 58 | * shellcheck warns about unreachable command in tests ([94cc929](https://gitlab.com/xebis/repository-template/commit/94cc92958c7ba3c4d93166669bbd8f119c8c813c)) 59 | * when a hook is installed setup script has a wrong icon ([86b113b](https://gitlab.com/xebis/repository-template/commit/86b113b16e34320c00d194ec405432b2a813ac5c)) 60 | 61 | 62 | ### Features 63 | 64 | * add .editorconfig ([b5b2894](https://gitlab.com/xebis/repository-template/commit/b5b2894327d6863405f1d5bcd00b0ef8aabfe6d6)) 65 | * json validation and linting ([6e7af63](https://gitlab.com/xebis/repository-template/commit/6e7af631576c1e5ad522d5f8fbf9255d0f0b06da)) 66 | 67 | # [0.25.0](https://gitlab.com/xebis/repository-template/compare/v0.24.0...v0.25.0) (2023-02-04) 68 | 69 | 70 | ### Features 71 | 72 | * add codespell pre-commit hook ([76bb588](https://gitlab.com/xebis/repository-template/commit/76bb5885d321197a1820498349887fff747822f5)) 73 | 74 | # [0.24.0](https://gitlab.com/xebis/repository-template/compare/v0.23.1...v0.24.0) (2022-10-09) 75 | 76 | 77 | ### Features 78 | 79 | * add pre-commit useless excludes check ([a72a834](https://gitlab.com/xebis/repository-template/commit/a72a834cf006b5ae0892888740934ac466632d80)) 80 | 81 | ## [0.23.1](https://gitlab.com/xebis/repository-template/compare/v0.23.0...v0.23.1) (2022-08-14) 82 | 83 | 84 | ### Bug Fixes 85 | 86 | * skip pre-commit hook variable doesn't work without gitlab token ([845da3f](https://gitlab.com/xebis/repository-template/commit/845da3f3839dc574404d27a748de7446263f3758)) 87 | 88 | # [0.23.0](https://gitlab.com/xebis/repository-template/compare/v0.22.0...v0.23.0) (2022-01-07) 89 | 90 | 91 | ### Features 92 | 93 | * secrets.sh symbols better match shellib's style ([6707322](https://gitlab.com/xebis/repository-template/commit/67073223278b94d520d0474e181a09b6619af8e0)) 94 | 95 | # [0.22.0](https://gitlab.com/xebis/repository-template/compare/v0.21.0...v0.22.0) (2022-01-05) 96 | 97 | 98 | ### Features 99 | 100 | * add pre-commit hooks git-check, git-dirty, protect-first-parent ([2a6e4a9](https://gitlab.com/xebis/repository-template/commit/2a6e4a9af4bfa10a8e46c4e6cbc203a3672f66e3)) 101 | * remove pre-push unstaged files check, pre-commit warning is enough ([f534123](https://gitlab.com/xebis/repository-template/commit/f534123d991470d7e69ea205f9fcb546ecbcfd42)) 102 | 103 | # [0.21.0](https://gitlab.com/xebis/repository-template/compare/v0.20.0...v0.21.0) (2022-01-03) 104 | 105 | 106 | ### Bug Fixes 107 | 108 | * scripts/update failed on unspecified shellib branch ([3f580e0](https://gitlab.com/xebis/repository-template/commit/3f580e0fa5b018eb29cb2ebabdcc6fa8a9ea192f)) 109 | 110 | 111 | ### Features 112 | 113 | * switch from own package management to shellib pkgs ([efc518e](https://gitlab.com/xebis/repository-template/commit/efc518e6f7956bd38b533321df59155a01bb2339)) 114 | 115 | # [0.20.0](https://gitlab.com/xebis/repository-template/compare/v0.19.1...v0.20.0) (2021-12-19) 116 | 117 | 118 | ### Features 119 | 120 | * add shellib ([bd555a5](https://gitlab.com/xebis/repository-template/commit/bd555a5c7f3eee8f64374d1ad1bca56417052667)) 121 | 122 | ## [0.19.1](https://gitlab.com/xebis/repository-template/compare/v0.19.0...v0.19.1) (2021-12-19) 123 | 124 | 125 | ### Bug Fixes 126 | 127 | * scripts/setup remove unnecessary output ([12d712c](https://gitlab.com/xebis/repository-template/commit/12d712c7f397f310c209311c3a8d48d6272427d2)) 128 | 129 | # [0.19.0](https://gitlab.com/xebis/repository-template/compare/v0.18.0...v0.19.0) (2021-12-16) 130 | 131 | 132 | ### Bug Fixes 133 | 134 | * pre-commit script test fails on env var collision with bats ([d57fc8a](https://gitlab.com/xebis/repository-template/commit/d57fc8a129a0bff11f37b66fd3628aa7addcb85b)) 135 | * pre-push hook should run pre-commit hooks on changed, not all files ([531b584](https://gitlab.com/xebis/repository-template/commit/531b584e65d785c827ec77f3c8617d8299e5b1cd)) 136 | * pre-push hook should run pre-commit hooks on changed, not all files ([c34c0d6](https://gitlab.com/xebis/repository-template/commit/c34c0d665c1810bd440e649ea53893dc1877ce65)) 137 | * pre-push hook skips changed files ([acc8021](https://gitlab.com/xebis/repository-template/commit/acc8021691cd9ece4f641724c085c1974a063d6c)) 138 | * refactored scripts fails on non-existent environment variable ([f2cd6a1](https://gitlab.com/xebis/repository-template/commit/f2cd6a1d1cbd475fcee5f35efb2858766c7d5767)) 139 | * shellcheck fails on included scripts ([e40610a](https://gitlab.com/xebis/repository-template/commit/e40610a1e811ce2b40d9917ff25e57999071ea3c)) 140 | 141 | 142 | ### Features 143 | 144 | * add git-merge-commit hook ([9a3be21](https://gitlab.com/xebis/repository-template/commit/9a3be21f0ec7699d432af075dd0b93348c4d6a57)) 145 | * add gitleaks pre-commit hook ([b402316](https://gitlab.com/xebis/repository-template/commit/b40231671bf636703dd58c4a68a6609b55afee34)) 146 | * add scripts/test test runner ([07e5554](https://gitlab.com/xebis/repository-template/commit/07e55545e731559eb8cf69e955a06ee5c790b232)) 147 | * anti-todo hook checks word boundaries and replaces check-sanity ([a05773d](https://gitlab.com/xebis/repository-template/commit/a05773d6b5f964b41a0de0f510e90850a2a47a65)) 148 | * rename tools to scripts ([bffa6e4](https://gitlab.com/xebis/repository-template/commit/bffa6e413c54d4abf4709e7a1216855112f81879)) 149 | * rename, rewrite, and refactor scripts/check-sanity ([2513adc](https://gitlab.com/xebis/repository-template/commit/2513adc7e00299e33f37106291930319dbb1bf6e)) 150 | * rename, rewrite, and refactor scripts/pre-commit ([1664a1d](https://gitlab.com/xebis/repository-template/commit/1664a1d3d5459bf1612908c75b8b2e7127e1442b)) 151 | * rename, rewrite, and refactor scripts/update ([52a657e](https://gitlab.com/xebis/repository-template/commit/52a657e1e04e25a8eb5626246390b2a71ef02b3f)) 152 | * rewrite, and refactor scripts/pre-push ([59a24f3](https://gitlab.com/xebis/repository-template/commit/59a24f3a42fddff669dd92d799a16214e0c28232)) 153 | * split setup-repo to bootstrap and setup scripts ([f85da8a](https://gitlab.com/xebis/repository-template/commit/f85da8a1fdbd5e6ee0eeaa17cf3a82869e012ace)) 154 | 155 | # [0.18.0](https://gitlab.com/xebis/repository-template/compare/v0.17.2...v0.18.0) (2021-12-04) 156 | 157 | 158 | ### Features 159 | 160 | * pre-releases and maintenance releases ([c96f563](https://gitlab.com/xebis/repository-template/commit/c96f5638ce52c18f14cacfc62ff0f9f92c366ad0)) 161 | 162 | # [0.18.0-beta.1](https://gitlab.com/xebis/repository-template/compare/v0.17.2...v0.18.0-beta.1) (2021-12-04) 163 | 164 | 165 | ### Features 166 | 167 | * pre-releases and maintenance releases ([c96f563](https://gitlab.com/xebis/repository-template/commit/c96f5638ce52c18f14cacfc62ff0f9f92c366ad0)) 168 | 169 | ## [0.17.2](https://gitlab.com/xebis/repository-template/compare/v0.17.1...v0.17.2) (2021-12-04) 170 | 171 | 172 | ### Bug Fixes 173 | 174 | * tools/check-sanity shouldn't traverse through hidden directories ([70105c4](https://gitlab.com/xebis/repository-template/commit/70105c4fa54e2208036cddf63f85ed465795cce7)) 175 | 176 | ## [0.17.1](https://gitlab.com/xebis/repository-template/compare/v0.17.0...v0.17.1) (2021-12-04) 177 | 178 | 179 | ### Bug Fixes 180 | 181 | * add misssing git submodules update ([5b186d2](https://gitlab.com/xebis/repository-template/commit/5b186d25c0315bf973daf5660bf883d3824ceaaf)) 182 | 183 | # [0.17.0](https://gitlab.com/xebis/repository-template/compare/v0.16.0...v0.17.0) (2021-12-03) 184 | 185 | 186 | ### Bug Fixes 187 | 188 | * bats files are formatted as well ([e3a4567](https://gitlab.com/xebis/repository-template/commit/e3a4567d1a87ce25c2df198a799ad28b9363523f)) 189 | * lint fails on script-must-have-extension pre-commit hook ([9cc2ce0](https://gitlab.com/xebis/repository-template/commit/9cc2ce09ab0d585672e240b37d9eb1902eaebbb0)) 190 | * lint fails on shfmt pre-commit hook ([ca1f033](https://gitlab.com/xebis/repository-template/commit/ca1f033755dd8e1b9452a433c5863a55f5b62fa9)) 191 | 192 | 193 | ### Features 194 | 195 | * add bats ([c5083b3](https://gitlab.com/xebis/repository-template/commit/c5083b38f5e1a74f6ac13951d02b0feed4162d33)) 196 | * add bats-support, bats-assert, and bats-file test helpers ([27f546c](https://gitlab.com/xebis/repository-template/commit/27f546cab564f1dd869ac74271e6df7aa1875f16)) 197 | 198 | # [0.16.0](https://gitlab.com/xebis/repository-template/compare/v0.15.0...v0.16.0) (2021-11-29) 199 | 200 | 201 | ### Bug Fixes 202 | 203 | * sourcing tools/secrets.sh lead to unexpected shell exits ([e550540](https://gitlab.com/xebis/repository-template/commit/e550540c350efda767e3c208578c128680a34702)) 204 | 205 | 206 | ### Features 207 | 208 | * add check-mailmap pre-commit hook ([f6ed3fe](https://gitlab.com/xebis/repository-template/commit/f6ed3fe430acb41e50d7526b4ebaf74fdc2a1294)) 209 | * rename tools script load-secrets.sh to secrets.sh ([1fc4cd5](https://gitlab.com/xebis/repository-template/commit/1fc4cd5d5929742562a0df7c2247f851afd8a6c6)) 210 | 211 | # [0.15.0](https://gitlab.com/xebis/repository-template/compare/v0.14.3...v0.15.0) (2021-11-21) 212 | 213 | 214 | ### Features 215 | 216 | * add tools/load-secrets script ([871059d](https://gitlab.com/xebis/repository-template/commit/871059d6ae3f44b468335bd4f6607fb1da05ec4a)) 217 | 218 | ## [0.14.3](https://gitlab.com/xebis/repository-template/compare/v0.14.2...v0.14.3) (2021-10-31) 219 | 220 | 221 | ### Bug Fixes 222 | 223 | * don't miss yaml to be done tags with a leading space ([3b00e5e](https://gitlab.com/xebis/repository-template/commit/3b00e5eadb490bd3c9c9d09d9807b9db3212be8a)) 224 | 225 | ## [0.14.2](https://gitlab.com/xebis/repository-template/compare/v0.14.1...v0.14.2) (2021-07-09) 226 | 227 | 228 | ### Bug Fixes 229 | 230 | * gitlab ci linter is not skipped when gitlab personal token is set ([c374fca](https://gitlab.com/xebis/repository-template/commit/c374fca04c12c2415f4067410738d80e9d3a12d5)) 231 | 232 | ## [0.14.1](https://gitlab.com/xebis/repository-template/compare/v0.14.0...v0.14.1) (2021-06-11) 233 | 234 | 235 | ### Bug Fixes 236 | 237 | * update-repo should have pre-commit update first, gc last ([859a2e2](https://gitlab.com/xebis/repository-template/commit/859a2e2054b20af116c5c383f3031e677e1dade6)) 238 | 239 | # [0.14.0](https://gitlab.com/xebis/repository-template/compare/v0.13.0...v0.14.0) (2021-06-10) 240 | 241 | 242 | ### Bug Fixes 243 | 244 | * add temporary skipping gitlab-ci-linter ([06a570b](https://gitlab.com/xebis/repository-template/commit/06a570b66c674cfb4c4b722fa4725fe61fd30d9c)) 245 | * ignore todos at binary files ([700a630](https://gitlab.com/xebis/repository-template/commit/700a630b15345c2884db33bef39d5ce127080e4a)) 246 | 247 | 248 | ### Features 249 | 250 | * add tools update-repo pre-commit gc ([ac6f5cc](https://gitlab.com/xebis/repository-template/commit/ac6f5cc8838cdea75dbf4cf67ad1b6f57e8d4811)) 251 | 252 | # [0.13.0](https://gitlab.com/xebis/repository-template/compare/v0.12.0...v0.13.0) (2021-05-22) 253 | 254 | 255 | ### Bug Fixes 256 | 257 | * setup-repo, update-repo don't work out of the repo root ([d6dda69](https://gitlab.com/xebis/repository-template/commit/d6dda69d1cb8516765c9aec62e916d356e388d89)) 258 | 259 | 260 | ### Features 261 | 262 | * update pre-commit hooks to v4.0.1 ([445b985](https://gitlab.com/xebis/repository-template/commit/445b985f1566aa066eb5046e594c089ec4b9c6aa)) 263 | 264 | # [0.12.0](https://gitlab.com/xebis/repository-template/compare/v0.11.2...v0.12.0) (2021-05-12) 265 | 266 | 267 | ### Features 268 | 269 | * add contributing and code of conduct ([778c360](https://gitlab.com/xebis/repository-template/commit/778c3608a89f38dca81f52db3388676594162235)) 270 | * add license templates ([58d6cff](https://gitlab.com/xebis/repository-template/commit/58d6cff0f63836bfadf47a774343151dcbdcad1f)) 271 | * add readme template ([25f1649](https://gitlab.com/xebis/repository-template/commit/25f1649747151b87fd4e76a8deff73e559f3d717)) 272 | 273 | ## [0.11.2](https://gitlab.com/xebis/repository-template/compare/v0.11.1...v0.11.2) (2021-05-09) 274 | 275 | 276 | ### Bug Fixes 277 | 278 | * setup-repo script misses sudo ([40e608c](https://gitlab.com/xebis/repository-template/commit/40e608c38bd69c0eb8d29f161e3535fdd07c36b6)) 279 | 280 | ## [0.11.1](https://gitlab.com/xebis/repository-template/compare/v0.11.0...v0.11.1) (2021-04-24) 281 | 282 | 283 | ### Bug Fixes 284 | 285 | * gitlint fails on release commits from semantic-release ([01b6018](https://gitlab.com/xebis/repository-template/commit/01b6018e8f808a040d7a3f6e71b761e8e45843ba)) 286 | 287 | # [0.11.0](https://gitlab.com/xebis/repository-template/compare/v0.10.0...v0.11.0) (2021-04-24) 288 | 289 | 290 | ### Features 291 | 292 | * add ci schedule runs nightly test set ([aa2a745](https://gitlab.com/xebis/repository-template/commit/aa2a7450b1b0f7e3714e38ae2128f289fdc9fa57)) 293 | 294 | # [0.10.0](https://gitlab.com/xebis/repository-template/compare/v0.9.0...v0.10.0) (2021-04-24) 295 | 296 | 297 | ### Features 298 | 299 | * add gitlab ci runs full test set ([4ed1651](https://gitlab.com/xebis/repository-template/commit/4ed165187e42ac644b13b64e941f8a26e5b1e702)) 300 | * add pre-commit runs quick test set ([328fb5f](https://gitlab.com/xebis/repository-template/commit/328fb5fc20bada7d24bcb26a2488c2b1bac116f7)) 301 | * add pre-push runs reduced test set ([0bd0f89](https://gitlab.com/xebis/repository-template/commit/0bd0f8917da3b372cad840acb48f0beb1601f54e)) 302 | 303 | # [0.9.0](https://gitlab.com/xebis/repository-template/compare/v0.8.0...v0.9.0) (2021-04-24) 304 | 305 | 306 | ### Bug Fixes 307 | 308 | * ci should perform sanity check as well ([af503ed](https://gitlab.com/xebis/repository-template/commit/af503ed0f35390fb8566dab719ad4f1ec25a0799)) 309 | 310 | 311 | ### Features 312 | 313 | * add pre-push hook with additional checks ([4310948](https://gitlab.com/xebis/repository-template/commit/4310948c096a2b076dcb3cbcc199b2b2ca3aa919)) 314 | 315 | # [0.8.0](https://gitlab.com/xebis/repository-template/compare/v0.7.0...v0.8.0) (2021-04-24) 316 | 317 | 318 | ### Bug Fixes 319 | 320 | * ci fails on shfmt not found ([0853877](https://gitlab.com/xebis/repository-template/commit/08538771fcd45d0b421745e319f0fdc9a4b0d8d4)) 321 | 322 | 323 | ### Features 324 | 325 | * add shfmt and shellcheck ([a219ad9](https://gitlab.com/xebis/repository-template/commit/a219ad9857ca51f7fe24b4fd7a8bf4647bd68951)) 326 | 327 | # [0.7.0](https://gitlab.com/xebis/repository-template/compare/v0.6.0...v0.7.0) (2021-04-24) 328 | 329 | 330 | ### Features 331 | 332 | * add gitlab ci linter ([c7e8119](https://gitlab.com/xebis/repository-template/commit/c7e8119ee401ff456e334feb0bdb2b3d1ee02e16)) 333 | 334 | # [0.6.0](https://gitlab.com/xebis/repository-template/compare/v0.5.0...v0.6.0) (2021-04-24) 335 | 336 | 337 | ### Features 338 | 339 | * add yamllint ([c0daf9b](https://gitlab.com/xebis/repository-template/commit/c0daf9b020a4cfeca63a1a31a3ddc8b56ea8becd)) 340 | 341 | # [0.5.0](https://gitlab.com/xebis/repository-template/compare/v0.4.0...v0.5.0) (2021-04-24) 342 | 343 | 344 | ### Features 345 | 346 | * add markdownlint ([0e5ed4e](https://gitlab.com/xebis/repository-template/commit/0e5ed4ee1d3daa80418226faee1e263014b8d725)) 347 | 348 | # [0.4.0](https://gitlab.com/xebis/repository-template/compare/v0.3.0...v0.4.0) (2021-04-24) 349 | 350 | 351 | ### Features 352 | 353 | * add jumanjihouse pre-commit hooks ([532eec1](https://gitlab.com/xebis/repository-template/commit/532eec108e89f7bc1eacca91736a549f843932b0)) 354 | * add more pre-commit hooks ([aa2bf32](https://gitlab.com/xebis/repository-template/commit/aa2bf321ff5dc804d9f0af89ba4b65f67d44321f)) 355 | 356 | # [0.3.0](https://gitlab.com/xebis/repository-template/compare/v0.2.0...v0.3.0) (2021-04-23) 357 | 358 | 359 | ### Features 360 | 361 | * add gitlint ([3a58bf2](https://gitlab.com/xebis/repository-template/commit/3a58bf23994a734dffe3220ef199675f89caa808)) 362 | 363 | # [0.2.0](https://gitlab.com/xebis/repository-template/compare/v0.1.0...v0.2.0) (2021-04-23) 364 | 365 | 366 | ### Features 367 | 368 | * add pre-commit hooks installation to git hooks ([cf9aa7c](https://gitlab.com/xebis/repository-template/commit/cf9aa7c54f1d1db1f683416cd9c44ca7505e715d)) 369 | * add setup-repo script ([70e9427](https://gitlab.com/xebis/repository-template/commit/70e9427dc97d6b9a0495e9c678d32db9526bb3ec)) 370 | * add update-repo script ([3d0945d](https://gitlab.com/xebis/repository-template/commit/3d0945d3539eb7f83cf1fd6f29129d8d772fd63c)) 371 | 372 | # [0.1.0](https://gitlab.com/xebis/repository-template/compare/v0.0.0...v0.1.0) (2021-04-23) 373 | 374 | 375 | ### Bug Fixes 376 | 377 | * add missing ci git installation ([d367743](https://gitlab.com/xebis/repository-template/commit/d36774353017183b27377eaa33e705756203be91)) 378 | 379 | 380 | ### Features 381 | 382 | * add semantic releases to gitlab, github when merged to main ([cdb6007](https://gitlab.com/xebis/repository-template/commit/cdb600778dea50709fbc454044cca271efafca2e)) 383 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | - Using welcoming and inclusive language 12 | - Being respectful of differing viewpoints and experiences 13 | - Gracefully accepting constructive criticism 14 | - Focusing on what is best for the community 15 | - Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | - Trolling, insulting/derogatory comments, and personal or political attacks 21 | - Public or private harassment 22 | - Publishing other's private information, such as a physical or electronic address, without explicit permission 23 | - Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, available at . 44 | 45 | For answers to common questions about this code of conduct, see 46 | 47 | The origin of this document is [GitHub - PurpleBooth/a-good-readme-template: A template to make good README.md](https://github.com/PurpleBooth/a-good-readme-template). 48 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please follow common sense when creating issues and [the GitHub flow](https://guides.github.com/introduction/flow/) when creating merge requests. 4 | 5 | ## Issues 6 | 7 | Issues are very valuable to this project. 8 | 9 | - Ideas are a valuable source of contributions others can make 10 | - Problems show where this project is lacking 11 | - With a question, you show where contributors can improve the user experience 12 | 13 | Thank you for creating them. 14 | 15 | ## Merge Requests 16 | 17 | Merge requests are a great way to get your ideas into this repository. 18 | 19 | When deciding if I merge in a merge request I look at the following things: 20 | 21 | ### Does it state intent 22 | 23 | You should be clear about which problem you're trying to solve with your 24 | contribution. 25 | 26 | For example: 27 | 28 | > Add link to code of conduct in README.md 29 | 30 | Doesn't tell me anything about why you're doing that 31 | 32 | > Add link to code of conduct in README.md because users don't always look in the CONTRIBUTING.md 33 | 34 | Tells me the problem that you have found, and the merge request shows me the action you have taken to solve it. 35 | 36 | ### Is it of good quality 37 | 38 | - There are no spelling mistakes 39 | - It reads well 40 | - For English language contributions: Has a good score on [Grammarly](grammarly.com) or [Hemingway Editor](http://www.hemingwayapp.com/) 41 | 42 | ### Does it move this repository closer to my vision for the repository 43 | 44 | The aim of this repository is documented at [README](README.md). 45 | 46 | ### Does it follow the contributor covenant 47 | 48 | This repository has a [code of conduct](CODE_OF_CONDUCT.md), I will remove things that do not respect it. 49 | 50 | The origin of this document is [GitHub - PurpleBooth/a-good-readme-template: A template to make good README.md](https://github.com/PurpleBooth/a-good-readme-template). 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Martin Bruzina 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Repository Template 3 | 4 | 5 | 6 | ![GitHub top language](https://img.shields.io/github/languages/top/xebis/repository-template) 7 | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) 8 | [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org) 9 | [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) 10 | 11 | ![GitHub](https://img.shields.io/github/license/xebis/repository-template) 12 | ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/xebis/repository-template) 13 | ![GitHub issues](https://img.shields.io/github/issues/xebis/repository-template) 14 | ![GitHub last commit](https://img.shields.io/github/last-commit/xebis/repository-template) 15 | [![pipeline status](https://gitlab.com/xebis/repository-template/badges/main/pipeline.svg?ignore_skipped=true)](https://gitlab.com/xebis/repository-template/-/commits/main) 16 | [![Latest Release](https://gitlab.com/xebis/repository-template/-/badges/release.svg)](https://gitlab.com/xebis/repository-template/-/releases) 17 | 18 | Highly automated, up-to-date, and well-documented repository template. 19 | 20 | Checks for common problems, Markdown, YAML, Bash, formats, lints, and tests before committing or pushing so you don't have any surprises at CI or when releasing your code to GitLab and GitHub! 21 | 22 | **The project is under active development.** 23 | 24 | 25 | ## The Purpose 26 | 27 | The purpose is to have a template repository and to have it _well-manageable_ and _well-maintainable_ by both human beings and automation tools. 28 | 29 | The rationale behind this is that taking care of tens or hundreds of repositories while keeping them working, tidy, consistent, and up-to-date, might be a daunting task. 30 | 31 | The way how to achieve the desired state of manageability and maintainability is to _unify_ and _automate_ workflow to allow frequent small changes for multiple projects at scale. 32 | 33 | Objectives: 34 | 35 | - Simple and easy environment check and setup 36 | - Fast and unified code change contribution 37 | - Automated and reliable code change propagation (build, testing, integration, publication or deployment, and release) 38 | 39 | Strategies and tactics to achieve objectives: 40 | 41 | 1. Automate 42 | 2. Automate 43 | 3. Automate 44 | 45 | 46 | ## Table of Contents 47 | 48 | - [Features](#features) 49 | - [Releases](#releases) 50 | - [Hooks](#hooks) 51 | - [Tests](#tests) 52 | - [Test Set](#test-set) 53 | - [Templates](#templates) 54 | - [Images](#images) 55 | - [Installation and Configuration](#installation-and-configuration) 56 | - [Local Environment](#local-environment) 57 | - [GitLab Project](#gitlab-project) 58 | - [GitLab - GitHub Synchronization](#gitlab---github-synchronization) 59 | - [GitLab CI Settings](#gitlab-ci-settings) 60 | - [GitLab CI Nightly Pipeline](#gitlab-ci-nightly-pipeline) 61 | - [Usage](#usage) 62 | - [Usage Examples](#usage-examples) 63 | - [Contributing](#contributing) 64 | - [Testing](#testing) 65 | - [Test at Docker Container](#test-at-docker-container) 66 | - [To-Do list](#to-do-list) 67 | - [Roadmap](#roadmap) 68 | - [Credits and Acknowledgments](#credits-and-acknowledgments) 69 | - [Copyright and Licensing](#copyright-and-licensing) 70 | - [Changelog and News](#changelog-and-news) 71 | - [Notes and References](#notes-and-references) 72 | - [Dependencies](#dependencies) 73 | - [Recommendations](#recommendations) 74 | - [Suggestions](#suggestions) 75 | - [Further Reading](#further-reading) 76 | 77 | ## Features 78 | 79 | Optimized for [GitHub flow](https://guides.github.com/introduction/flow/), easily adjustable to [GitLab flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html) or any other workflow. 80 | 81 | ![Example of the full workflow](images/workflow-full.png) 82 | 83 | - Automated workflow using [git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks), and [GitLab CI](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/) 84 | - Git `commit` scans committed codebase change, git `push` scans pushed codebase change, and GitLab CI scans the whole codebase, and the [hooks](#hooks) are applied 85 | - Commit messages are checked using [gitlint](https://github.com/jorisroovers/gitlint), commit message should follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 86 | - Git `commit` (both regular and merge) is normalized, checked, and tested: 87 | - Runs [hooks](#hooks) 88 | - Runs [fast test set](tests/fast.set) 89 | - Lints the commit message 90 | - Git `push` is checked, and tested: 91 | - Runs [hooks](#hooks) 92 | - Runs [reduced test set](tests/reduced.set) 93 | - Create merge request directly by **git push options**, see 94 | - GitLab CI run is checked, and tested: 95 | - Lints the latest commit message (except `release` commits) 96 | - Runs [hooks](#hooks) 97 | - Runs [full test set](tests/full.set) on non-scheduled pipeline runs 98 | - Runs [nightly test set](tests/nightly.set) on scheduled pipeline runs 99 | - Skip GitLab CI run if commit message contains `[ci skip]` or `[skip ci]`, using any capitalization, or pass **git push option** `ci.skip` (`git push -o ci.skip` git >= 2.17, `git push --push-option=ci.skip` git >= 2.10) 100 | - Hooks could be skipped by setting `SKIP` variable to a comma-separated list of skipped hooks, for example, `SKIP=forbid-new-submodules,gitlab-ci-linter git commit` 101 | - Hooks could be run manually `pre-commit run -a --hook-stage manual` 102 | - When `feat` or `fix` commit is present, GitLab CI job `release` publishes release using [semantic-release/semantic-release](https://github.com/semantic-release/semantic-release) 103 | - When merged to the maintenance release branch (`N.N.x` or `N.x.x` or `N.x` with `N` being a number), publish maintenance [release](#releases) 104 | - When merged to `next`, `next-major`, `beta`, or `alpha` branch, publish pre-release [release](#releases) 105 | - When merged to the `main` branch publish [release](#releases) 106 | - Included scripts for your convenience in a fashion of [The GitHub Blog: Scripts to Rule Them All](https://github.blog/2015-06-30-scripts-to-rule-them-all/) 107 | - `scripts/setup` setups `commit-msg`, `pre-commit`, `pre-merge-commit`, and `pre-push` hooks 108 | - `scripts/bootstrap` installs dependencies 109 | - `scripts/test` runs tests, as arguments accepts test files or test sets (see `*.bats` or `*.set` files at the [tests](tests) directory) 110 | - `scripts/update` updates used dependencies 111 | - [EditorConfig](.editorconfig) 112 | 113 | ### Releases 114 | 115 | ![Example of a release workflow](images/workflow-release.png) 116 | 117 | Release branches must match regex `^(((0|[1-9]\d*)\.)(((0|[1-9]\d*|x)\.)?x)|main|next(-major)?|beta|alpha)$`, see . 118 | 119 | When `feat` or `fix` commit is present in the merge (to be more precise since the last release tag) to `main`, `next`, `next-major`, `beta`, `alpha`, _`major`_`.x`, or _`major.minor`_`.x` branch, the publish release: 120 | 121 | - Determines major, minor, or patch version bump using [semantic-release/commit-analyzer](https://github.com/semantic-release/commit-analyzer) 122 | - Generates release notes using [semantic-release/release-notes-generator](https://github.com/semantic-release/release-notes-generator) 123 | - Generates changelog using [semantic-release/changelog](https://github.com/semantic-release/changelog) 124 | - Commits changelog and new version using [semantic-release/git](https://github.com/semantic-release/git) 125 | - Publishes new version by creating a tag using [semantic-release/gitlab](https://github.com/semantic-release/gitlab) 126 | - Publishes new version by creating a tag using [semantic-release/github](https://github.com/semantic-release/github) 127 | - Semantic-release skips release if commit contains `[skip release]` or `[release skip]` in the commit message 128 | 129 | ### Hooks 130 | 131 | [Pre-commit](https://github.com/pre-commit/pre-commit) is by default configured to run these hooks: 132 | 133 | - Lints git commit message using [gitlint](https://github.com/jorisroovers/gitlint) 134 | - Prevents messages not following [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 135 | - Prevents words `wip`, `todo`, or `tbd` at the commit message title 136 | - Enforces max file size to 1024 kB using [pre-commit/pre-commit-hooks: check-added-large-files](https://github.com/pre-commit/pre-commit-hooks#check-added-large-files) 137 | - Prevents case insensitive filename conflict using [pre-commit/pre-commit-hooks: check-case-conflict](https://github.com/pre-commit/pre-commit-hooks#check-case-conflict) 138 | - Enforces executables have shebangs using [pre-commit/pre-commit-hooks: check-executables-have-shebangs](https://github.com/pre-commit/pre-commit-hooks#check-executables-have-shebangs) 139 | - Loads JSON to validate it using [pre-commit/pre-commit-hooks: check-json](https://github.com/pre-commit/pre-commit-hooks#check-json) 140 | - Prevents merge conflict strings using [pre-commit/pre-commit-hooks: check-merge-conflict](https://github.com/pre-commit/pre-commit-hooks#check-merge-conflict) 141 | - Prevents stale symlinks using [pre-commit/pre-commit-hooks: check-symlinks](https://github.com/pre-commit/pre-commit-hooks#check-symlinks) 142 | - Prevents non-permanent GitHub links using [pre-commit/pre-commit-hooks: check-vcs-permalinks](https://github.com/pre-commit/pre-commit-hooks#check-vcs-permalinks) 143 | - Prevents destroyed symlinks using [pre-commit/pre-commit-hooks: destroyed-symlinks](https://github.com/pre-commit/pre-commit-hooks#destroyed-symlinks) 144 | - Prevents the existence of private keys using [pre-commit/pre-commit-hooks: detect-private-key](https://github.com/pre-commit/pre-commit-hooks#detect-private-key) 145 | - Enforces files end with empty newline using [pre-commit/pre-commit-hooks: end-of-file-fixer](https://github.com/pre-commit/pre-commit-hooks#end-of-file-fixer) 146 | - Prevents UTF8 byte order marker using [pre-commit/pre-commit-hooks: fix-byte-order-marker](https://github.com/pre-commit/pre-commit-hooks#fix-byte-order-marker) 147 | - Prevents new git submodules [pre-commit/pre-commit-hooks: forbid-new-submodules](https://github.com/pre-commit/pre-commit-hooks#forbid-new-submodules) 148 | - Converts line endings to LF using [pre-commit/pre-commit-hooks: mixed-line-ending](https://github.com/pre-commit/pre-commit-hooks#mixed-line-ending) 149 | - Prevents commits to protected branches using [pre-commit/pre-commit-hooks: no-commit-to-branch](https://github.com/pre-commit/pre-commit-hooks#no-commit-to-branch) 150 | - Enforces pretty JSON format using [pre-commit/pre-commit-hooks: pretty-format-json](https://github.com/pre-commit/pre-commit-hooks#pretty-format-json) 151 | - Prevents trailing whitespace characters using [pre-commit/pre-commit-hooks: trailing-whitespace](https://github.com/pre-commit/pre-commit-hooks#trailing-whitespace) 152 | - Prevents botched name/email translations in git history using [jumanjihouse/pre-commit-hooks: check-mailmap](https://github.com/jumanjihouse/pre-commit-hooks#check-mailmap) 153 | - Prevents binary files from being added by accident using [jumanjihouse/pre-commit-hooks: forbid-binary](https://github.com/jumanjihouse/pre-commit-hooks#forbid-binary) 154 | - Prevents git conflict markers and whitespace errors by using [jumanjihouse/pre-commit-hooks: git-check](https://github.com/jumanjihouse/pre-commit-hooks#git-check) 155 | - Prevents modified, staged, or untracked by using [jumanjihouse/pre-commit-hooks: git-dirty](https://github.com/jumanjihouse/pre-commit-hooks#git-dirty) 156 | - Prevents foxtrot merges by using [jumanjihouse/pre-commit-hooks: protect-first-parent](https://github.com/jumanjihouse/pre-commit-hooks#protect-first-parent) 157 | - Enforces executable scripts have no extension using [jumanjihouse/pre-commit-hooks: script-must-not-have-extension](https://github.com/jumanjihouse/pre-commit-hooks#script-must-not-have-extension) 158 | - Enforces non-executable script libraries have extension using [jumanjihouse/pre-commit-hooks: script-must-have-extension](https://github.com/jumanjihouse/pre-commit-hooks#script-must-have-extension) 159 | - When manually run, prevents hooks not applied to any file in the repository using [pre-commit/pre-commit-hooks: meta hook check-hooks-apply](https://pre-commit.com/#meta-check_hooks_apply) 160 | - Prevents useless pre-commit hook exclude directives using [pre-commit/pre-commit-hooks: meta hook check-useless-excludes](https://pre-commit.com/#meta-check_useless_excludes) 161 | - Checks spelling using [GitHub - codespell-project/codespell: check code for common misspellings](https://github.com/codespell-project/codespell) 162 | - Lints Markdown using [igorshubovych/markdownlint-cli: MarkdownLint Command Line Interface](https://github.com/igorshubovych/markdownlint-cli) (except [CHANGELOG.md](CHANGELOG.md)) 163 | - Lints YAML using [adrienverge/yamllint](https://github.com/adrienverge/yamllint) 164 | - Lints [`.gitlab-ci.yml`](.gitlab-ci.yml) file using [devopshq/gitlab-ci-linter](https://gitlab.com/devopshq/gitlab-ci-linter) when `GL_TOKEN` environment variable is set to **GitLab Personal Token** 165 | - When MR (merge request) is created or updated, or when manually run, prevents presence of words `wip`, `todo`, or `tbd` preceded with `#` at a text file, checked by regex `(?i)#\s*\b(wip|todo|tbd)\b`, see 166 | - Lints shell scripts formatting using [mvdan/sh: A shell parser, formatter, and interpreter with bash support; includes shfmt](https://github.com/mvdan/sh) 167 | - Checks shell scripts using [koalaman/shellcheck: ShellCheck, a static analysis tool for shell scripts](https://github.com/koalaman/shellcheck) 168 | - Detects hardcoded secrets like passwords, api keys, and tokens in git repos using [GitHub - gitleaks/gitleaks: Scan git repos (or files) for secrets using regex and entropy key](https://github.com/gitleaks/gitleaks) 169 | - For other formats and rules see [pre-commit: Supported hooks](https://pre-commit.com/hooks.html), there are many for .NET, Ansible, AWS, C, CMake, CSV, C++, Chef, Dart, Docker, Flutter, git, GitHub, GitLab, Go, HTML, INI, Java, JavaScript, Jenkins, Jinja, JSON, Kotlin, Lisp, Lua, Mac, Markdown, Node.js, Perl, PHP, Prometheus, Protocol Buffers, Puppet, Python, R, Ruby, Rust, Shell, Swift, Terraform, TOML, Typescript, XML, YAML, ... or create new using regular expressions. 170 | 171 | ### Tests 172 | 173 | Tests are written using BATS - [GitHub - bats-core/bats-core: Bash Automated Testing System](https://github.com/bats-core/bats-core), [GitHub - bats-core/bats-support: Supporting library for Bats test helpers](https://github.com/bats-core/bats-support), [GitHub - bats-core/bats-assert: Common assertions for Bats](https://github.com/bats-core/bats-assert), and [GitHub - bats-core/bats-file: Common filesystem assertions for Bats](https://github.com/bats-core/bats-file) and organized in test sets. 174 | 175 | #### Test Set 176 | 177 | Test set is a simple text file format. Each line must begin or end without leading or trailing whitespace. Each line should contain included test sets (`*.set`), test files to be run (`*.bats`), comments starting with `#` as the first character on the line, or empty lines. File paths are relative to the test set file. 178 | 179 | Example: 180 | 181 | ```text 182 | # Commented and empty lines are ignored 183 | 184 | another.set 185 | 186 | script1.bats 187 | script2.bats 188 | script3.bats 189 | ``` 190 | 191 | ### Templates 192 | 193 | - [Readme Template](templates/README.md) 194 | - Licenses 195 | - [MIT License Template](templates/MIT-LICENSE) 196 | - [NO License Template](templates/NO-LICENSE) 197 | 198 | ### Images 199 | 200 | - [Git workflow examples & template](images/workflow.drawio) 201 | - [Example of the full workflow](images/workflow-full.png) 202 | - [Example of a release workflow](images/workflow-release.png) 203 | - [Example of a feature workflow](images/workflow-feature.png) 204 | - [Example of a bugfix workflow](images/workflow-fix.png) 205 | 206 | ## Installation and Configuration 207 | 208 | ### Local Environment 209 | 210 | Clone the project with `--recursive` option, run `scripts/bootstrap` as root to install dependencies, `scripts/setup` for a complete setup, and adjust to Your needs. Make sure **GL_TOKEN**: [GitLab Personal Access Token](https://gitlab.com/-/profile/personal_access_tokens) with scope `api` is present, otherwise `gitlab-ci-linter` is skipped. To load secrets you can use shell extension like [direnv](https://direnv.net/), encryption like [SOPS](https://github.com/getsops/sops), or secrets manager [HashiCorp Vault](https://www.vaultproject.io/), **please make sure you won't commit your secrets**. 211 | 212 | Example: 213 | 214 | ```bash 215 | git clone --recursive git@gitlab.com:xebis/repository-template.git 216 | cd repository-template 217 | sudo scripts/bootstrap 218 | scripts/setup 219 | ``` 220 | 221 | Run `scripts/update` from time to time to update repository dependencies. 222 | 223 | ### GitLab Project 224 | 225 | #### GitLab - GitHub Synchronization 226 | 227 | To create working GitLab to GitHub repository synchronization: 228 | 229 | - Prepare GitHub token, let's call it `GitLab GitHub Sync`, with scopes: 230 | - `repo` (and `repo:status`, `repo_deployment`, `public_repo`, `repo:invite`, `security_events`) 231 | - `workflow` 232 | - `write:packages` (and `read:packages`) 233 | - `delete:packages` 234 | - Have or create a GitHub repository 235 | - Set up GitLab GitHub synchronization: Settings 236 | - Repository 237 | - Mirroring repositories, _Expand_ 238 | - _Add new mirror_: 239 | - Git repository URL: ****, please replace _user_, _org_, and _repo_ 240 | - Mirror direction: **Push** 241 | - Password: **`GitLab GitHub Sync` token** 242 | - Keep divergent refs: **On** or **Off** 243 | - Mirror only protected branches: **On** (in that case all release, maintenance, and pre-release branches should be set as protected, otherwise GitHub release would fail on non-existent branch) or **Off** 244 | 245 | #### GitLab CI Settings 246 | 247 | Set up release and GitLab CI Linter tokens as the GitLab group or the GitLab project variable: 248 | 249 | - **GL_TOKEN**: [GitLab Personal Access Token](https://gitlab.com/-/profile/personal_access_tokens) with scopes `api` and `write_repository`. 250 | - If the variable is protected, GitLab CI job `lint` is skipped on non-protected branches. 251 | - **GH_TOKEN**: [GitHub Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/about-authentication-to-github#authenticating-with-the-api) with at least scopes `repo` for a private repository or `public_repo` for a public repository. 252 | - If the variable is protected, then releasing to GitHub works only from protected branches. 253 | 254 | - Settings 255 | - CI/CD 256 | - Variables, _Expand_ 257 | - _Add Variable_: 258 | - Key: `GL_TOKEN` or `GH_TOKEN` 259 | - Value: _token_ 260 | - Flags: 261 | - Protect variable: **On** (GitLab & GitHub Releases and GitLab CI Linter will work only on protected branches) or **Off** (insecure - accessible to anybody, who can create a commit in GitLab) 262 | 263 | #### GitLab CI Nightly Pipeline 264 | 265 | Set up the GitLab scheduled pipeline: 266 | 267 | - CI/CD 268 | - Schedules 269 | - _New schedule_ 270 | - _Fill_ and _Save pipeline schedule_ 271 | 272 | ## Usage 273 | 274 | Simply fork the repository at [GitLab](https://gitlab.com/xebis/repository-template/-/forks/new) or [GitHub](https://github.com/xebis/repository-template/fork), **delete** all git tags, and **tag** the last commit to the desired starting version, e.g. `v0.0.0`. Clone the repository with `--recursive` option, run `sudo scripts/bootstrap`, `scripts/setup`, `scripts/update`, at [`.pre-commit-config.yaml`](.pre-commit-config.yaml) replace `gitlab-ci-linter` project with _your project_, and enjoy! 275 | 276 | - `git commit`, or `git merge` runs checks on changed files and runs [fast test set](tests/fast.set) 277 | - `git push` runs checks on all files and runs [reduced test set](tests/reduced.set) 278 | - GitLab `push`, `merge request` runs checks on all files and runs [full test set](tests/reduced.set) 279 | - GitLab `merge to main` runs checks on all files, runs [full test set](tests/reduced.set), and publishes a new version release 280 | - GitLab `schedule` runs checks on all files, runs [nightly test set](tests/nightly.set) 281 | - Run `scripts/update` manually from time to time to update repository dependencies 282 | 283 | ### Usage Examples 284 | 285 | For usage examples, you might take a look at: 286 | 287 | - [GitHub - xebis/shellib: Simple Bash scripting library.](https://github.com/xebis/shellib) - example of version bumping and creating deb package 288 | - [GitHub - xebis/infrastructure-template: Template for automated GitOps and IaC in a cloud. GitLab CI handles static and dynamic environments. Environments are created, updated, and destroyed by Terraform, then configured by cloud-init and Ansible.](https://github.com/xebis/infrastructure-template) - example of GitOps (IaC + MRs + CI/CD) and multiple environments orchestration 289 | - [GitHub - xebis/xebis-ansible-collection: A collection of Xebis shared Ansible roles.](https://github.com/xebis/xebis-ansible-collection) 290 | 291 | ## Contributing 292 | 293 | Please read [CONTRIBUTING](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting merge requests to us. 294 | 295 | ### Testing 296 | 297 | - Git hooks check a lot of things for you, including running automated tests `scripts/test full` 298 | - Make sure all `scripts/*`, git hooks, and GitLab pipelines work as expected, testing checklist: 299 | 300 | - `scripts/*` scripts - covered by unit tests `tests/*` 301 | - [ ] [`scripts/bootstrap`](scripts/bootstrap) 302 | - [ ] [`scripts/pre-commit`](scripts/pre-commit) 303 | - [ ] [`scripts/pre-push`](scripts/pre-push) 304 | - [ ] [`scripts/setup`](scripts/setup) 305 | - [ ] [`scripts/test`](scripts/test) 306 | - [ ] [`scripts/update`](scripts/update) 307 | - Local working directory 308 | - [ ] `git commit` runs `pre-commit` hook-type `commit-msg` and [`scripts/pre-commit`](scripts/pre-commit) 309 | - [ ] `git merge` 310 | - [ ] Fast-forward shouldn't run any hooks or scripts 311 | - [ ] Automatically resolved `merge commit` runs `pre-commit` hook-type `commit-msg` and [`scripts/pre-commit`](scripts/pre-commit) 312 | - [ ] Manually resolved `merge commit` runs `pre-commit` hook-type `commit-msg` and [`scripts/pre-commit`](scripts/pre-commit) 313 | - [ ] `git push` runs [`scripts/pre-push`](scripts/pre-push) 314 | - [ ] `pre-commit run -a --hook-stage manual` runs all hooks and `check-hooks-apply` hook fails on `check-symlinks` and `forbid-binary` 315 | - GitLab CI 316 | - [ ] Commit in _non_-`main` branch runs `validate:lint` and `validate:test-*-full` 317 | - [ ] Merge to `main` branch runs `validate:lint`, `validate:test-*-full`, and `release:release` 318 | - [ ] With a new `feat` or `fix` commit releases a new version in GitHub and GitLab 319 | - [ ] [GitHub - xebis/repository-template ∙ Releases](https://github.com/xebis/repository-template/releases) 320 | - [ ] [GitLab - xebis/repository-template ∙ Releases](https://gitlab.com/xebis/repository-template/-/releases) 321 | - [ ] Without a new feature or fix commit does not release a new version 322 | - [ ] Scheduled (nightly) pipeline runs `validate:lint` and `validate:test-*-nightly` 323 | 324 | #### Test at Docker Container 325 | 326 | To test your changes in a different environment, you might try to run a Docker container and test it from there. 327 | 328 | Run a disposal Docker container: 329 | 330 | - `sudo docker run -it --rm -v "$(pwd)":/repository-template alpine:latest` 331 | - `sudo docker run -it --rm -v "$(pwd)":/repository-template --entrypoint bash node:latest` 332 | 333 | In the container: 334 | 335 | ```bash 336 | cd repository-template 337 | # Set variables GL_TOKEN and GH_TOKEN when needed 338 | # Put here commands from .gitlab-ci.yml job:before_script and job:script 339 | # For example job test-full: 340 | apk -U upgrade 341 | apk add bats 342 | bats tests 343 | # Result is similar to: 344 | # 1..1 345 | # ok 1 dummy test 346 | ``` 347 | 348 | ## To-Do list 349 | 350 | - [ ] Fix workaround for pre-commit `local` hook `shellcheck` - shellcheck has duplicated parameters from `.shellcheckrc`, because these are not taken into account 351 | 352 | ## Roadmap 353 | 354 | - [ ] Find a satisfactory way how to manage (list, install, update) dependencies across various distributions and package managers 355 | - [ ] Add [jumanjihouse/pre-commit-hooks hook protect-first-parent](https://github.com/jumanjihouse/pre-commit-hooks#protect-first-parent) 356 | - [ ] Speed up CI/CD by preparing a set of Docker images with pre-installed dependencies for each CI/CD stage, or by cache for `apk`, `pip`, and `npm` 357 | 358 | ## Credits and Acknowledgments 359 | 360 | - [Martin Bružina](https://bruzina.cz/) - Author 361 | 362 | ## Copyright and Licensing 363 | 364 | - [MIT License](LICENSE) 365 | - Copyright © 2021 Martin Bružina 366 | 367 | ## Changelog and News 368 | 369 | - [Changelog](CHANGELOG.md) 370 | 371 | ## Notes and References 372 | 373 | ### Dependencies 374 | 375 | - [git](https://git-scm.com/) 376 | - [GitLab: The complete DevOps platform](https://about.gitlab.com/) 377 | - [GitLab: Continuous Integration (CI) with GitLab](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/) 378 | - [GitLab: GitLab Runner](https://docs.gitlab.com/runner/) 379 | - [Docker Hub - Alpine](https://hub.docker.com/_/alpine) 380 | - [Docker Hub - Node](https://hub.docker.com/_/node) 381 | - [GitHub - semantic-release/semantic-release: Fully automated version management and package publishing](https://github.com/semantic-release/semantic-release) 382 | - [pre-commit: A framework for managing and maintaining multi-language pre-commit hooks](https://pre-commit.com/) 383 | - [pre-commit: Supported hooks](https://pre-commit.com/hooks.html) 384 | - [GitHub - pre-commit/pre-commit-hooks: Some out-of-the-box hooks for pre-commit](https://github.com/pre-commit/pre-commit-hooks) 385 | - [GitHub - jumanjihouse/pre-commit-hooks: git pre-commit hooks that work with http://pre-commit.com/](https://github.com/jumanjihouse/pre-commit-hooks) 386 | - [GitHub - jorisroovers/gitlint: Linting for your git commit messages](https://github.com/jorisroovers/gitlint) 387 | - [GitHub - codespell-project/codespell: check code for common misspellings](https://github.com/codespell-project/codespell) 388 | - [GitHub - igorshubovych/markdownlint-cli: MarkdownLint Command Line Interface](https://github.com/igorshubovych/markdownlint-cli) 389 | - [GitHub - adrienverge/yamllint: A linter for YAML files.](https://github.com/adrienverge/yamllint) 390 | - [GitLab - devopshq/gitlab-ci-linter](https://gitlab.com/devopshq/gitlab-ci-linter) 391 | - [GitHub - mvdan/sh: A shell parser, formatter, and interpreter with bash support; includes shfmt](https://github.com/mvdan/sh) 392 | - [GitHub - koalaman/shellcheck: ShellCheck, a static analysis tool for shell scripts](https://github.com/koalaman/shellcheck) 393 | - [GitHub - gitleaks/gitleaks: Scan git repos (or files) for secrets using regex and entropy key](https://github.com/gitleaks/gitleaks) 394 | - For scripts and hooks: 395 | - Tools standard in any Linux (Bash, Coreutils, Grep) 396 | - [GitHub - xebis/shellib: Simple Bash scripting library.](https://github.com/xebis/shellib) 397 | - [GitHub - bats-core/bats-core: Bash Automated Testing System](https://github.com/bats-core/bats-core) 398 | - [GitHub - bats-core/bats-support: Supporting library for Bats test helpers](https://github.com/bats-core/bats-support) 399 | - [GitHub - bats-core/bats-assert: Common assertions for Bats](https://github.com/bats-core/bats-assert) 400 | - [GitHub - bats-core/bats-file: Common filesystem assertions for Bats](https://github.com/bats-core/bats-file) 401 | 402 | ### Recommendations 403 | 404 | - [Commitizen](https://commitizen-tools.github.io/commitizen/) 405 | - [readme.so: Easiest Way to Create A README](https://readme.so/) 406 | - [GitHub - matiassingers/awesome-readme: A curated list of awesome READMEs](https://github.com/matiassingers/awesome-readme) 407 | - [Grammarly](https://www.grammarly.com/) or [Hemingway Editor](http://www.hemingwayapp.com/) 408 | - [EditorConfig](https://editorconfig.org/) 409 | - [direnv](https://direnv.net/), [SOPS](https://github.com/getsops/sops), or [HashiCorp Vault](https://www.vaultproject.io/) 410 | 411 | ### Suggestions 412 | 413 | - [Shields.io: Quality metadata badges for open source projects](https://shields.io/) 414 | - [Visual Studio Code](https://code.visualstudio.com/) with [Extensions for Visual Studio Code](https://marketplace.visualstudio.com/VSCode): 415 | - DX & UX 416 | - [One Dark Pro++ (TPack)](https://marketplace.visualstudio.com/items?itemName=SeyyedKhandon.tpack) - includes [One Dark Pro](https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme), [Material Icon Theme](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme), and [FiraCode Font](https://marketplace.visualstudio.com/items?itemName=SeyyedKhandon.firacode) 417 | - [DX Enhancer Pack (EPack)](https://marketplace.visualstudio.com/items?itemName=SeyyedKhandon.epack) - includes [Project Manager](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager), [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments), [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced), [file-size](https://marketplace.visualstudio.com/items?itemName=zh9528.file-size), [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens), and [Path Intellisense](https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense) 418 | - [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) 419 | - [Gremlins tracker for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=nhoizey.gremlins) 420 | - English, and grammar: 421 | - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) 422 | - [Grammarly (unofficial)](https://marketplace.visualstudio.com/items?itemName=znck.grammarly) 423 | - Git, and GitLab: 424 | - [Git Extension Pack (GPack)](https://marketplace.visualstudio.com/items?itemName=SeyyedKhandon.gpack) - includes [GitLens — Git supercharged](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens), [Git File History](https://marketplace.visualstudio.com/items?itemName=pomber.git-file-history), [Conventional Commits](https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits), and [Checkpoints](https://marketplace.visualstudio.com/items?itemName=micnil.vscode-checkpoints) 425 | - [gitignore](https://marketplace.visualstudio.com/items?itemName=codezombiech.gitignore) 426 | - [Git Graph](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph) 427 | - [Git History](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory) 428 | - [GitLab Workflow](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow) 429 | - Markdown: 430 | - [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) - includes [Github Markdown Preview](https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview), [Markdown Checkboxes](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-checkbox), [Markdown Emoji](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-emoji), [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf), and [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) 431 | - [Paste Image](https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image) 432 | - [Markdown yaml Preamble](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-yaml-preamble) 433 | - [HTTP/s and relative link checker](https://marketplace.visualstudio.com/items?itemName=blackmist.LinkCheckMD) 434 | - Bash or shell: 435 | - [Bash IDE](https://marketplace.visualstudio.com/items?itemName=mads-hartmann.bash-ide-vscode) 436 | - [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck) 437 | - [shell-format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format) 438 | - [Bats (Bash Automated Testing System)](https://marketplace.visualstudio.com/items?itemName=jetmartin.bats) 439 | 440 | ### Further Reading 441 | 442 | - [Git - Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) 443 | - [Conventional Commits - Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/) 444 | - [Semantic Versioning - Semantic Versioning 2.0.0](https://semver.org/), [GitHub - romversioning/romver: Romantic Versioning Specification](https://github.com/romversioning/romver), or [Sentimental Versioning](http://sentimentalversioning.org/) 445 | - [Wikipedia: README](https://en.wikipedia.org/wiki/README) 446 | - [Make a README: Because no one can read your mind (yet)](https://www.makeareadme.com/) 447 | - [GitHub - PurpleBooth/a-good-readme-template: A template to make good README.md](https://github.com/PurpleBooth/a-good-readme-template) 448 | - [Wikipedia: Contributing guidelines](https://en.wikipedia.org/wiki/Contributing_guidelines) 449 | - [Wikipedia: Code of conduct](https://en.wikipedia.org/wiki/Code_of_conduct) 450 | - [Contributor Covenant: A Code of Conduct for Open Source Communities](https://www.contributor-covenant.org/) 451 | - [Programster's Blog: Git Workflows](https://blog.programster.org/git-workflows) 452 | - [GitHub Guides: Understanding the GitHub flow](https://guides.github.com/introduction/flow/) 453 | - [GitLab Docs: Introduction to GitLab Flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html) 454 | - [GitHub Docs: Introduction to GitHub Actions](https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/introduction-to-github-actions) - contains CI/CD workflow terminology 455 | - [The GitHub Blog: Scripts to Rule Them All](https://github.blog/2015-06-30-scripts-to-rule-them-all/) 456 | -------------------------------------------------------------------------------- /cspell.config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | language: en 3 | version: "0.2" 4 | dictionaries: 5 | - en_US 6 | - softwareTerms 7 | - bash 8 | - words 9 | words: 10 | - Bružina 11 | - codespell 12 | - Coreutils 13 | - direnv 14 | - drawio 15 | - gitleaks 16 | - gitlint 17 | - markdownlint 18 | - roadmap 19 | - shellib 20 | - venv 21 | - Xebis 22 | flagWords: [] 23 | -------------------------------------------------------------------------------- /images/workflow-feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/old-xebis/repository-template/42af5a5dc3c31a8177f6ad79a9b47088636e0d24/images/workflow-feature.png -------------------------------------------------------------------------------- /images/workflow-fix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/old-xebis/repository-template/42af5a5dc3c31a8177f6ad79a9b47088636e0d24/images/workflow-fix.png -------------------------------------------------------------------------------- /images/workflow-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/old-xebis/repository-template/42af5a5dc3c31a8177f6ad79a9b47088636e0d24/images/workflow-full.png -------------------------------------------------------------------------------- /images/workflow-release.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/old-xebis/repository-template/42af5a5dc3c31a8177f6ad79a9b47088636e0d24/images/workflow-release.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pre-commit 2 | gitlint 3 | codespell 4 | yamllint 5 | -------------------------------------------------------------------------------- /scripts/bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | LANG=C 5 | 6 | # shellcheck source=./shellib/shellib.sh 7 | . "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/shellib/shellib.sh" 8 | 9 | # Install dependencies 10 | function install_dependencies() { 11 | pkgs install 'apt:git' 'apt:python3-pip' 'snap:node' 'npm:markdownlint-cli' 'snap:shfmt' 'snap:shellcheck' 'apt:bats' 12 | pip install -r requirements.txt 13 | } 14 | 15 | # Skip execution under test 16 | if [ "${BASH_SOURCE[0]}" == "${0}" ]; then 17 | install_dependencies 18 | fi 19 | -------------------------------------------------------------------------------- /scripts/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | LANG=C 5 | 6 | # shellcheck source=./shellib/shellib.sh 7 | . "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/shellib/shellib.sh" 8 | 9 | # Check committed codebase changes 10 | function run_pre_commit() { 11 | # Skip GitLab CI Linter if GitLab Personal Access Token is not set 12 | if [ -z "${GL_TOKEN:-}" ]; then 13 | if [ -z "${SKIP:-}" ]; then 14 | export SKIP=gitlab-ci-linter 15 | else 16 | export SKIP="$SKIP,gitlab-ci-linter" 17 | fi 18 | else 19 | export GITLAB_PRIVATE_TOKEN="$GL_TOKEN" 20 | fi 21 | 22 | pre-commit hook-impl --hook-type=pre-commit --config=.pre-commit-config.yaml --hook-dir "$(cd "$(dirname "$0")" && pwd)" -- "$@" 23 | } 24 | 25 | # Skip execution under test 26 | if [ "${BASH_SOURCE[0]}" == "${0}" ]; then 27 | run_pre_commit "$@" 28 | scripts/test tests/fast.set 29 | fi 30 | -------------------------------------------------------------------------------- /scripts/pre-push: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | LANG=C 5 | 6 | # shellcheck source=./shellib/shellib.sh 7 | . "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/shellib/shellib.sh" 8 | 9 | # Check pushed codebase changes or without arguments the whole codebase 10 | function run_pre_commit() { 11 | # Skip GitLab CI Linter if GitLab Personal Access Token is not set 12 | if [ -z "${GL_TOKEN:-}" ]; then 13 | if [ -z "${SKIP:-}" ]; then 14 | export SKIP=gitlab-ci-linter 15 | else 16 | export SKIP="$SKIP,gitlab-ci-linter" 17 | fi 18 | else 19 | export GITLAB_PRIVATE_TOKEN="$GL_TOKEN" 20 | fi 21 | 22 | pre-commit hook-impl --hook-type=pre-push --config=.pre-commit-config.yaml --hook-dir "$(cd "$(dirname "$0")" && pwd)" -- "$@" 23 | } 24 | 25 | # Skip execution if under test 26 | if [ "${BASH_SOURCE[0]}" == "${0}" ]; then 27 | run_pre_commit "$@" 28 | scripts/test tests/reduced.set 29 | fi 30 | -------------------------------------------------------------------------------- /scripts/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | LANG=C 5 | 6 | # shellcheck source=./shellib/shellib.sh 7 | . "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/shellib/shellib.sh" 8 | 9 | function setup_hook() { 10 | local hook="$1" 11 | local script="scripts/${2:-$1}" 12 | 13 | if [ -L ".git/hooks/$hook" ] && [ "$(readlink .git/hooks/"$hook")" == "../../$script" ]; then 14 | info "$1 hook is installed" 15 | else 16 | if [ ! -f ".git/hooks/$hook" ]; then 17 | if ln -s "../../$script" ".git/hooks/$hook"; then 18 | info "$hook hook has been installed" "$symbol_done" 19 | else 20 | err "$hook hook installation failed, cannot create symbolic link" "$symbol_failed" 21 | return "$status_err" 22 | fi 23 | else 24 | err "$hook cannot be installed" "$symbol_failed" 25 | info "Try to remove '.git/hooks/$hook' first" "$symbol_tip" 26 | return "$status_err" 27 | fi 28 | fi 29 | } 30 | 31 | function setup() { 32 | # Install pre-commit for commit-msg hook 33 | if pre-commit install -t commit-msg 1>/dev/null; then 34 | info 'commit-msg hook is installed' 35 | else 36 | err 'commit-msg hook installation failed' 37 | return "$status_err" 38 | fi 39 | 40 | REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && git rev-parse --show-toplevel)" 41 | 42 | pushd "$REPO_DIR" 1>/dev/null 43 | 44 | # Setup git hooks 45 | if ! setup_hook 'pre-commit' || 46 | ! setup_hook 'pre-merge-commit' 'pre-commit' || 47 | ! setup_hook 'pre-push'; then 48 | return "$status_err" 49 | fi 50 | 51 | popd 1>/dev/null 52 | 53 | # Check if GL_TOKEN is set 54 | if [ -z "${GL_TOKEN:-}" ]; then 55 | notice 'environment variable GL_TOKEN is not set, pre-commit hook gitlab-ci-linter will be skipped' 56 | info 'You might set up environment variable GL_TOKEN' "$symbol_tip" 57 | else 58 | info 'GL_TOKEN is set' 59 | fi 60 | } 61 | 62 | # Main 63 | function main() { 64 | if is_root; then 65 | err "Shouldn't be run as root" 66 | info 'Try again as non-root' "$symbol_tip" 67 | return "$status_err" 68 | else 69 | setup 70 | fi 71 | } 72 | 73 | # Skip execution under test 74 | if [ "${BASH_SOURCE[0]}" == "${0}" ]; then 75 | main 76 | fi 77 | -------------------------------------------------------------------------------- /scripts/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | LANG=C 5 | 6 | # shellcheck source=./shellib/shellib.sh 7 | . "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/shellib/shellib.sh" 8 | 9 | # Run test file $1 10 | function run_test_file() { 11 | if [ -f "$1" ] && [ -r "$1" ]; then 12 | info "running test file $1:" "$symbol_doing" 13 | if bats "$1"; then 14 | info "$1 done" "$symbol_done" 15 | else 16 | err "$1 failed" "$symbol_failed" 17 | return "$status_err" 18 | fi 19 | else 20 | err "Could not run test file $1" 21 | return "$status_err" 22 | fi 23 | } 24 | 25 | # Run named test set $1 26 | function run_test_set() { 27 | if [ -f "$1" ] && [ -r "$1" ]; then 28 | info "running test set $1" "$symbol_doing" 29 | test_path="$(dirname "$1")" 30 | mapfile -t set_lines <"$1" 31 | for set_line in "${set_lines[@]}"; do 32 | case "$set_line" in 33 | '') ;; # Ignore empty lines 34 | \#*) ;; # Ignore comments 35 | *\.bats | *\.set) 36 | run_test "$test_path/$set_line" 37 | ;; 38 | *) 39 | warn "Unexpected test set $1 line $set_line" 40 | ;; 41 | esac 42 | done 43 | else 44 | err "Could not run test set $1" 45 | return "$status_err" 46 | fi 47 | } 48 | 49 | # Run test file or test set $1 50 | function run_test() { 51 | case "$1" in 52 | *.bats) 53 | run_test_file "$1" 54 | ;; 55 | *.set) 56 | run_test_set "$1" 57 | ;; 58 | *) 59 | err "Unknown test type $1" 60 | usage 61 | return "$status_err" 62 | ;; 63 | esac 64 | } 65 | 66 | # Print usage 67 | function usage() { 68 | echo "Usage: ${TEST_ARGV:-$0} [path [...]]]" 69 | echo 70 | echo ' path Path to test file or test set' 71 | } 72 | 73 | # Main 74 | # For zero arguments: prints usage 75 | # One or more arguments: runs test 76 | function main() { 77 | if [ -z "${1+x}" ]; then 78 | usage 79 | return 80 | fi 81 | 82 | for arg in "$@"; do 83 | if [ -f "$arg" ]; then 84 | run_test "$arg" 85 | else 86 | err "Unknown test type $1" 87 | usage 88 | return "$status_err" 89 | fi 90 | done 91 | } 92 | 93 | # Skip execution under test 94 | if [ "${BASH_SOURCE[0]}" == "${0}" ]; then 95 | main "$@" 96 | fi 97 | -------------------------------------------------------------------------------- /scripts/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | LANG=C 5 | 6 | # shellcheck source=./shellib/shellib.sh 7 | . "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/shellib/shellib.sh" 8 | 9 | # Update repository pre-commit 10 | function update_pre_commit { 11 | pre-commit autoupdate 12 | pre-commit gc 13 | } 14 | 15 | # Update repository submodules 16 | function update_git_submodules() { 17 | git submodule update --remote --merge 18 | } 19 | 20 | # Skip execution under test 21 | if [ "${BASH_SOURCE[0]}" == "${0}" ]; then 22 | update_pre_commit 23 | update_git_submodules 24 | fi 25 | -------------------------------------------------------------------------------- /templates/MIT-LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) YEAR Subject 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/NO-LICENSE: -------------------------------------------------------------------------------- 1 | © Copyright YEAR Subject. All rights reserved. 2 | -------------------------------------------------------------------------------- /templates/README.md: -------------------------------------------------------------------------------- 1 | 2 | # _Project_ 3 | 4 | - _Change all emphasized texts_ 5 | - _Delete unused sections_ 6 | - _Use `code formatting`_ 7 | - _Replace `org` and `proj` in badges link with respective slugs_ 8 | 9 | ![GitHub top language](https://img.shields.io/github/languages/top/org/proj) 10 | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) 11 | [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org) 12 | [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) 13 | 14 | ![GitHub](https://img.shields.io/github/license/org/proj) 15 | ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/org/proj) 16 | ![GitHub issues](https://img.shields.io/github/issues/org/proj) 17 | ![GitHub last commit](https://img.shields.io/github/last-commit/org/proj) 18 | 19 | _A concise description of the project specifically._ 20 | 21 | **The project is under active development.** 22 | 23 | 24 | ## Table of Contents 25 | 26 | - [Features](#features) 27 | - [Installation and Configuration](#installation-and-configuration) 28 | - [Usage](#usage) 29 | - [Contributing](#contributing) 30 | - [Development](#development) 31 | - [Testing](#testing) 32 | - [Operations](#operations) 33 | - [Contact](#contact) 34 | - [Troubleshooting and Support](#troubleshooting-and-support) 35 | - [To-Do list](#to-do-list) 36 | - [Roadmap](#roadmap) 37 | - [Known Bugs](#known-bugs) 38 | - [Credits and Acknowledgments](#credits-and-acknowledgments) 39 | - [Copyright and Licensing](#copyright-and-licensing) 40 | - [Changelog and News](#changelog-and-news) 41 | - [Notes and References](#notes-and-references) 42 | - [Dependencies](#dependencies) 43 | - [Recommendations](#recommendations) 44 | - [Suggestions](#suggestions) 45 | - [Further Reading](#further-reading) 46 | 47 | ## Features 48 | 49 | _Features. Demos and visuals - images, animations, and videos are highly encouraged._ 50 | 51 | ## Installation and Configuration 52 | 53 | _Installation and configuration guidance._ 54 | 55 | ```shell 56 | # Installation steps 57 | ``` 58 | 59 | ## Usage 60 | 61 | _Usage examples._ 62 | 63 | ```shell 64 | # ... 65 | ``` 66 | 67 | ## Contributing 68 | 69 | Please read [CONTRIBUTING](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting merge requests to us. 70 | 71 | ### Development 72 | 73 | _Development stack and tooling._ 74 | 75 | ### Testing 76 | 77 | _Testing stack and how to run tests._ 78 | 79 | ### Operations 80 | 81 | _Operations._ 82 | 83 | ## Contact 84 | 85 | _Contacts._ 86 | 87 | ### Troubleshooting and Support 88 | 89 | _Troubleshooting and preferred ways of providing support._ 90 | 91 | ## To-Do list 92 | 93 | _TODO list._ 94 | 95 | ## Roadmap 96 | 97 | _Roadmap._ 98 | 99 | ## Known Bugs 100 | 101 | _Known Bugs._ 102 | 103 | ## Credits and Acknowledgments 104 | 105 | - [Name Surname](https://example.com/) - author 106 | - _Appreciation of other contributors is welcome_ 107 | 108 | ## Copyright and Licensing 109 | 110 | - [License Name](MIT-LICENSE) 111 | - Copyright © YEAR Subject 112 | 113 | ## Changelog and News 114 | 115 | - [Changelog](../CHANGELOG.md) 116 | - _List other important or interesting news here_ 117 | 118 | ## Notes and References 119 | 120 | ### Dependencies 121 | 122 | _List dependencies here, or delete the section, if none._ 123 | 124 | - [Web: Page](https://example.com/) - the preferred way of referencing 125 | - [Web Page Title](https://example.com/) - also OK 126 | - [GitHub - xebis/repository-template: Well-manageable and well-maintainable repository template.](https://github.com/xebis/repository-template) 127 | 128 | ### Recommendations 129 | 130 | _List recommended references here, or delete the section._ 131 | 132 | - [Shields.io: Quality metadata badges for open source projects](https://shields.io/) 133 | 134 | ### Suggestions 135 | 136 | _List suggested references here, or delete the section._ 137 | 138 | - [readme.so: Easiest Way to Create A README](https://readme.so/) 139 | 140 | ### Further Reading 141 | 142 | _List further reading links here, or delete the section._ 143 | 144 | - [Wikipedia: README](https://en.wikipedia.org/wiki/README) 145 | - [Make a README: Because no one can read your mind (yet)](https://www.makeareadme.com/) 146 | -------------------------------------------------------------------------------- /tests/bootstrap.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2317 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | LANG=C 6 | 7 | setup() { 8 | load 'helpers/bats-support/load' 9 | load 'helpers/bats-assert/load' 10 | 11 | export TEST_ARGV=('scripts/bootstrap') 12 | 13 | . scripts/bootstrap 14 | } 15 | 16 | @test 'scripts/bootstrap install_dependencies test' { 17 | function pkgs() { 18 | echo 'OK' 19 | } 20 | export -f pkgs 21 | function pip() { 22 | echo 'OK' 23 | } 24 | export -f pip 25 | 26 | run install_dependencies 27 | 28 | assert_line -n 0 'OK' 29 | assert_line -n 1 'OK' 30 | } 31 | -------------------------------------------------------------------------------- /tests/fast.set: -------------------------------------------------------------------------------- 1 | # Run with each commit - should be really fast and shallow, e.g. only a few 2 | # selected tests 3 | 4 | pre-commit.bats 5 | pre-push.bats 6 | -------------------------------------------------------------------------------- /tests/full.set: -------------------------------------------------------------------------------- 1 | # Run with each CI/CD pipeline - should be thorough and within CI/CD timeouts, 2 | # e.g. all unit, integration, E2E, performance, compatibility, and other tests 3 | 4 | reduced.set 5 | 6 | bootstrap.bats 7 | setup.bats 8 | update.bats 9 | -------------------------------------------------------------------------------- /tests/nightly.set: -------------------------------------------------------------------------------- 1 | # Run nightly by CI/CD 2 | 3 | full.set 4 | -------------------------------------------------------------------------------- /tests/pre-commit.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2317 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | LANG=C 6 | 7 | setup() { 8 | load 'helpers/bats-support/load' 9 | load 'helpers/bats-assert/load' 10 | 11 | export TEST_ARGV=('scripts/pre-commit') 12 | 13 | . scripts/pre-commit 14 | } 15 | 16 | @test 'scripts/pre-commit run_pre_commit test' { 17 | function pre-commit() { 18 | # shellcheck disable=SC2030,SC2031 19 | if [ -z "${GL_TOKEN:-}" ]; then 20 | echo 'Error' 21 | fi 22 | # shellcheck disable=SC2030,SC2031 23 | if [ -n "${SKIP:-}" ]; then 24 | echo "Skipping $SKIP" 25 | fi 26 | echo 'OK' 27 | } 28 | export -f pre-commit 29 | 30 | # shellcheck disable=SC2030,SC2031 31 | export GL_TOKEN='secret' 32 | unset SKIP 33 | run run_pre_commit 34 | 35 | assert_success 36 | assert_output 'OK' 37 | } 38 | 39 | @test 'scripts/pre-commit run_pre_commit skipped hook test' { 40 | function pre-commit() { 41 | # shellcheck disable=SC2030,SC2031 42 | if [ -z "${GL_TOKEN:-}" ]; then 43 | echo 'Error' 44 | fi 45 | # shellcheck disable=SC2030,SC2031 46 | if [ -n "${SKIP:-}" ]; then 47 | echo "Skipping $SKIP" 48 | fi 49 | echo 'OK' 50 | } 51 | export -f pre-commit 52 | 53 | # shellcheck disable=SC2030,SC2031 54 | export GL_TOKEN='secret' 55 | # shellcheck disable=SC2030,SC2031 56 | export SKIP='skipped-hook' 57 | run run_pre_commit 58 | 59 | assert_success 60 | assert_line -n 0 'Skipping skipped-hook' 61 | assert_line -n 1 'OK' 62 | } 63 | 64 | @test 'scripts/pre-commit run_pre_commit without GitLab token should skip gitlab-ci-linter test' { 65 | function pre-commit() { 66 | # shellcheck disable=SC2030,SC2031 67 | if [ -n "${SKIP:-}" ]; then 68 | echo "Skipping $SKIP" 69 | fi 70 | echo 'OK' 71 | } 72 | export -f pre-commit 73 | 74 | unset GL_TOKEN 75 | unset SKIP 76 | run run_pre_commit 77 | 78 | assert_success 79 | assert_line -n 0 'Skipping gitlab-ci-linter' 80 | assert_line -n 1 'OK' 81 | } 82 | 83 | @test 'scripts/pre-commit run_pre_commit without GitLab token and skipped hook should skip both test' { 84 | function pre-commit() { 85 | # shellcheck disable=SC2030,SC2031 86 | if [ -n "${SKIP:-}" ]; then 87 | # shellcheck disable=SC2030,SC2031 88 | echo "Skipping $SKIP" 89 | fi 90 | echo 'OK' 91 | } 92 | export -f pre-commit 93 | 94 | unset GL_TOKEN 95 | # shellcheck disable=SC2030,SC2031 96 | export SKIP='skipped-hook' 97 | run run_pre_commit 98 | 99 | assert_success 100 | assert_line -n 0 'Skipping skipped-hook,gitlab-ci-linter' 101 | assert_line -n 1 'OK' 102 | } 103 | -------------------------------------------------------------------------------- /tests/pre-push.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2317 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | LANG=C 6 | 7 | setup() { 8 | load 'helpers/bats-support/load' 9 | load 'helpers/bats-assert/load' 10 | 11 | export TEST_ARGV=('scripts/pre-push') 12 | 13 | . scripts/pre-push 14 | } 15 | 16 | @test 'scripts/pre-push run_pre_commit test' { 17 | function pre-commit() { 18 | # shellcheck disable=SC2030,SC2031 19 | if [ -z "${GL_TOKEN-}" ]; then 20 | echo 'Error' 21 | fi 22 | # shellcheck disable=SC2030,SC2031 23 | if [ -n "${SKIP:-}" ]; then 24 | echo "Skipping $SKIP" 25 | fi 26 | echo 'OK' 27 | } 28 | export -f pre-commit 29 | 30 | # shellcheck disable=SC2030,SC2031 31 | export GL_TOKEN='secret' 32 | unset SKIP 33 | run run_pre_commit 34 | 35 | assert_success 36 | assert_output 'OK' 37 | } 38 | 39 | @test 'scripts/pre-push run_pre_commit skipped hook test' { 40 | function pre-commit() { 41 | # shellcheck disable=SC2030,SC2031 42 | if [ -z "${GL_TOKEN:-}" ]; then 43 | echo 'Error' 44 | fi 45 | # shellcheck disable=SC2030,SC2031 46 | if [ -n "${SKIP:-}" ]; then 47 | echo "Skipping $SKIP" 48 | fi 49 | echo 'OK' 50 | } 51 | export -f pre-commit 52 | 53 | # shellcheck disable=SC2030,SC2031 54 | export GL_TOKEN='secret' 55 | # shellcheck disable=SC2030,SC2031 56 | export SKIP='skipped-hook' 57 | run run_pre_commit 58 | 59 | assert_success 60 | assert_line -n 0 'Skipping skipped-hook' 61 | assert_line -n 1 'OK' 62 | } 63 | 64 | @test 'scripts/pre-push run_pre_commit without GitLab token should skip gitlab-ci-linter test' { 65 | function pre-commit() { 66 | # shellcheck disable=SC2030,SC2031 67 | if [ -n "${SKIP:-}" ]; then 68 | echo "Skipping $SKIP" 69 | fi 70 | echo 'OK' 71 | } 72 | export -f pre-commit 73 | 74 | unset GL_TOKEN 75 | unset SKIP 76 | run run_pre_commit 77 | 78 | assert_success 79 | assert_line -n 0 'Skipping gitlab-ci-linter' 80 | assert_line -n 1 'OK' 81 | } 82 | 83 | @test 'scripts/pre-push run_pre_commit without GitLab token and skipped hook should skip both test' { 84 | function pre-commit() { 85 | # shellcheck disable=SC2030,SC2031 86 | if [ -n "${SKIP:-}" ]; then 87 | echo "Skipping $SKIP" 88 | fi 89 | echo 'OK' 90 | } 91 | export -f pre-commit 92 | 93 | unset GL_TOKEN 94 | # shellcheck disable=SC2030,SC2031 95 | export SKIP='skipped-hook' 96 | run run_pre_commit 97 | 98 | assert_success 99 | assert_line -n 0 'Skipping skipped-hook,gitlab-ci-linter' 100 | assert_line -n 1 'OK' 101 | } 102 | 103 | @test 'scripts/pre-push run_pre_commit with arguments and stdin test' { 104 | function pre-commit() { 105 | cat <&0 106 | } 107 | export -f pre-commit 108 | 109 | run run_pre_commit 'origin' 'remote' <<<'Test' 110 | 111 | assert_success 112 | assert_output 'Test' 113 | } 114 | -------------------------------------------------------------------------------- /tests/reduced.set: -------------------------------------------------------------------------------- 1 | # Run with each push - should be fast but representative, e.g. carefully 2 | # selected representative subset of unit, integration, and perhaps other fast 3 | # tests 4 | 5 | fast.set 6 | 7 | test.bats 8 | -------------------------------------------------------------------------------- /tests/setup.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2317 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | LANG=C 6 | 7 | setup() { 8 | load 'helpers/bats-support/load' 9 | load 'helpers/bats-assert/load' 10 | load 'helpers/bats-file/load' 11 | 12 | export TEST_ARGV=('scripts/setup') 13 | 14 | . scripts/setup 15 | } 16 | 17 | @test 'scripts/setup setup_hook hook exists success test' { 18 | local hook='test' 19 | local file=".git/hooks/$hook" 20 | 21 | [ -d '.git/hooks' ] || mkdir -p '.git/hooks' 22 | setup_hook "$hook" 23 | run setup_hook "$hook" 24 | rm "$file" 25 | 26 | assert_success 27 | assert_line -n 0 "scripts/setup ✓ $hook hook is installed" 28 | } 29 | 30 | @test 'scripts/setup setup_hook hook exists failed test' { 31 | local hook='test' 32 | local file=".git/hooks/$hook" 33 | 34 | [ -d '.git/hooks' ] || mkdir -p '.git/hooks' 35 | touch "$file" 36 | run setup_hook "$hook" 37 | rm "$file" 38 | 39 | assert_failure 40 | assert_line -n 0 "scripts/setup ☒ $hook cannot be installed" 41 | assert_line -n 1 "scripts/setup 💡 Try to remove '.git/hooks/$hook' first" 42 | } 43 | 44 | @test 'scripts/setup setup_hook hook installation failed test' { 45 | local hook='test/' 46 | local file=".git/hooks/$hook" 47 | 48 | [ -d '.git/hooks' ] || mkdir -p '.git/hooks' 49 | run setup_hook "$hook" 50 | 51 | assert_not_exist "$file" 52 | assert_failure 53 | assert_line -n 1 "scripts/setup ☒ $hook hook installation failed, cannot create symbolic link" 54 | } 55 | 56 | @test 'scripts/setup setup_hook hook installation success test' { 57 | local hook='test' 58 | local file=".git/hooks/$hook" 59 | 60 | [ -d '.git/hooks' ] || mkdir -p '.git/hooks' 61 | run setup_hook "$hook" 62 | 63 | assert_link_exist "$file" 64 | rm "$file" 65 | assert_success 66 | assert_output 'scripts/setup 🗹 test hook has been installed' 67 | } 68 | 69 | @test 'scripts/setup setup pre-commit install failed test' { 70 | function pre-commit() { 71 | return 1 72 | } 73 | export -f pre-commit 74 | 75 | run setup 76 | 77 | assert_failure 78 | assert_output 'scripts/setup ✗ commit-msg hook installation failed' 79 | } 80 | 81 | @test 'scripts/setup setup setup_hook failed test' { 82 | function pre-commit() { 83 | return 0 84 | } 85 | export -f pre-commit 86 | 87 | function git() { 88 | pwd 89 | } 90 | export -f git 91 | 92 | function setup_hook() { 93 | err 'setup hook installation failed' 94 | return 1 95 | } 96 | 97 | run setup 98 | 99 | assert_failure 100 | assert_line -n 0 'scripts/setup ✓ commit-msg hook is installed' 101 | assert_line -n 1 'scripts/setup ✗ setup hook installation failed' 102 | } 103 | 104 | @test 'scripts/setup setup without GL_TOKEN set success test' { 105 | function pre-commit() { 106 | return 0 107 | } 108 | export -f pre-commit 109 | 110 | function git() { 111 | pwd 112 | } 113 | export -f git 114 | 115 | function setup_hook() { 116 | return 0 117 | } 118 | 119 | unset GL_TOKEN 120 | 121 | run setup 122 | 123 | assert_success 124 | assert_line -n 0 'scripts/setup ✓ commit-msg hook is installed' 125 | assert_line -n 1 'scripts/setup 🛈 environment variable GL_TOKEN is not set, pre-commit hook gitlab-ci-linter will be skipped' 126 | assert_line -n 2 'scripts/setup 💡 You might set up environment variable GL_TOKEN' 127 | } 128 | 129 | @test 'scripts/setup setup with GL_TOKEN set success test' { 130 | function pre-commit() { 131 | return 0 132 | } 133 | export -f pre-commit 134 | 135 | function git() { 136 | pwd 137 | } 138 | export -f git 139 | 140 | function setup_hook() { 141 | return 0 142 | } 143 | 144 | export GL_TOKEN='******' 145 | 146 | run setup 147 | 148 | assert_success 149 | assert_line -n 0 'scripts/setup ✓ commit-msg hook is installed' 150 | assert_line -n 1 'scripts/setup ✓ GL_TOKEN is set' 151 | } 152 | 153 | @test 'scripts/setup main under root user test' { 154 | function is_root() { 155 | return 0 156 | } 157 | export -f is_root 158 | 159 | run main 160 | 161 | assert_failure 162 | assert_line -n 0 "scripts/setup ✗ Shouldn't be run as root" 163 | assert_line -n 1 "scripts/setup 💡 Try again as non-root" 164 | } 165 | 166 | @test 'scripts/setup main under non-root user test' { 167 | function is_root() { 168 | return 1 169 | } 170 | export -f is_root 171 | 172 | function setup() { 173 | return 0 174 | } 175 | export -f setup 176 | 177 | run main 178 | 179 | assert_success 180 | refute_output 181 | } 182 | -------------------------------------------------------------------------------- /tests/test.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2317 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | LANG=C 6 | 7 | setup() { 8 | load 'helpers/bats-support/load' 9 | load 'helpers/bats-assert/load' 10 | 11 | export TEST_ARGV=('scripts/test') 12 | 13 | . scripts/test 14 | } 15 | 16 | @test 'scripts/test run_test_file success test' { 17 | run run_test_file tests/update.bats 18 | 19 | assert_success 20 | last_line="${#lines[@]}" 21 | ((last_line--)) 22 | assert_line -n 0 'scripts/test … running test file tests/update.bats:' 23 | assert_line -n "$last_line" 'scripts/test 🗹 tests/update.bats done' 24 | } 25 | 26 | @test 'scripts/test run_test_file non-existent file test' { 27 | run run_test_file nonsense 28 | 29 | assert_failure 30 | assert_output 'scripts/test ✗ Could not run test file nonsense' 31 | } 32 | 33 | @test 'scripts/test run_test_file failing test file test' { 34 | function bats() { 35 | echo 'Error!' 36 | return 1 37 | } 38 | export -f bats 39 | 40 | run run_test_file tests/update.bats 41 | 42 | assert_failure 43 | assert_line -n 0 'scripts/test … running test file tests/update.bats:' 44 | assert_line -n 1 'Error!' 45 | assert_line -n 2 'scripts/test ☒ tests/update.bats failed' 46 | } 47 | 48 | @test 'scripts/test run_test_set success test' { 49 | function bats() { 50 | echo 'OK' 51 | } 52 | export -f bats 53 | 54 | run run_test_set tests/fast.set 55 | 56 | assert_success 57 | last_line="${#lines[@]}" 58 | ((last_line--)) 59 | assert_line -n 0 'scripts/test … running test set tests/fast.set' 60 | } 61 | 62 | @test 'scripts/test run_test_set non-existent test set test' { 63 | run run_test_set nonsense 64 | 65 | assert_failure 66 | assert_output 'scripts/test ✗ Could not run test set nonsense' 67 | } 68 | 69 | @test 'scripts/test run_test_set failing test set test' { 70 | function bats() { 71 | echo 'Error!' 72 | return 1 73 | } 74 | export -f bats 75 | 76 | run run_test_set tests/fast.set 77 | 78 | assert_failure 79 | assert_line -n 0 'scripts/test … running test set tests/fast.set' 80 | assert_line -n 2 'Error!' 81 | } 82 | 83 | @test 'scripts/test run_test success file test' { 84 | run run_test tests/update.bats 85 | 86 | assert_success 87 | last_line="${#lines[@]}" 88 | ((last_line--)) 89 | assert_line -n 0 'scripts/test … running test file tests/update.bats:' 90 | assert_line -n "$last_line" 'scripts/test 🗹 tests/update.bats done' 91 | } 92 | 93 | @test 'scripts/test run_test success set test' { 94 | function bats() { 95 | echo 'OK' 96 | } 97 | export -f bats 98 | 99 | run run_test tests/fast.set 100 | 101 | assert_success 102 | last_line="${#lines[@]}" 103 | ((last_line--)) 104 | assert_line -n 0 'scripts/test … running test set tests/fast.set' 105 | } 106 | 107 | @test 'scripts/test run_test non-existent test type test' { 108 | run run_test nonsense 109 | 110 | assert_failure 111 | assert_line -n 0 'scripts/test ✗ Unknown test type nonsense' 112 | assert_line -n 1 'Usage: scripts/test [path [...]]]' 113 | assert_line -n 2 ' path Path to test file or test set' 114 | } 115 | 116 | @test 'scripts/test run_test non-existent test' { 117 | run run_test nonsense.bats 118 | 119 | assert_failure 120 | assert_output 'scripts/test ✗ Could not run test file nonsense.bats' 121 | } 122 | 123 | @test 'scripts/test usage test' { 124 | run usage 125 | 126 | assert_success 127 | assert_line -n 0 'Usage: scripts/test [path [...]]]' 128 | assert_line -n 1 ' path Path to test file or test set' 129 | } 130 | 131 | @test 'scripts/test main with zero arguments test' { 132 | function usage() { 133 | echo 'Usage' 134 | } 135 | export -f usage 136 | 137 | run main 138 | 139 | assert_success 140 | assert_output 'Usage' 141 | } 142 | 143 | @test 'scripts/test main with test file argument test' { 144 | function run_test_file() { 145 | echo "OK: $1" 146 | } 147 | export -f run_test_file 148 | 149 | run main 'tests/update.bats' 150 | 151 | assert_success 152 | assert_output 'OK: tests/update.bats' 153 | } 154 | 155 | @test 'scripts/test main with test set argument test' { 156 | function run_test_set() { 157 | echo "OK: $1" 158 | } 159 | export -f run_test_set 160 | 161 | run main 'tests/fast.set' 162 | 163 | assert_success 164 | assert_output 'OK: tests/fast.set' 165 | } 166 | 167 | @test 'scripts/test main with two arguments success test' { 168 | function run_test_file() { 169 | echo "OK: $1" 170 | } 171 | function run_test_set() { 172 | echo "OK: $1" 173 | } 174 | 175 | export -f run_test_file 176 | export -f run_test_set 177 | 178 | run main 'tests/update.bats' 'tests/fast.set' 179 | 180 | assert_success 181 | assert_line -n 0 'OK: tests/update.bats' 182 | assert_line -n 1 'OK: tests/fast.set' 183 | } 184 | 185 | @test 'scripts/test main with two arguments one failed test' { 186 | function run_test_file() { 187 | echo "OK: $1" 188 | } 189 | function run_test_set() { 190 | echo "Err: $1" 191 | return 1 192 | } 193 | 194 | export -f run_test_file 195 | export -f run_test_set 196 | 197 | run main 'tests/update.bats' 'tests/fast.set' 198 | 199 | assert_failure 200 | assert_line -n 0 'OK: tests/update.bats' 201 | assert_line -n 1 'Err: tests/fast.set' 202 | } 203 | -------------------------------------------------------------------------------- /tests/update.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2317 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | LANG=C 6 | 7 | setup() { 8 | load 'helpers/bats-support/load' 9 | load 'helpers/bats-assert/load' 10 | 11 | . scripts/update 12 | } 13 | 14 | @test 'scripts/update update_pre_commit test' { 15 | function pre-commit() { 16 | echo 'OK' 17 | } 18 | export -f pre-commit 19 | 20 | run update_pre_commit 21 | 22 | assert_success 23 | assert_line -n 0 'OK' 24 | assert_line -n 1 'OK' 25 | } 26 | 27 | @test 'scripts/update update_git_submodules test' { 28 | function git() { 29 | echo 'OK' 30 | } 31 | export -f git 32 | 33 | run update_git_submodules 34 | 35 | assert_success 36 | assert_output 'OK' 37 | } 38 | --------------------------------------------------------------------------------