mirror of
https://github.com/reecetech/version-increment.git
synced 2025-12-21 14:35:44 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae1ae190dc | ||
|
|
81805365e1 | ||
|
|
c6ea11748a | ||
|
|
73ade5516c | ||
|
|
352a9961c8 | ||
|
|
a449b75848 | ||
|
|
0df84379a9 | ||
|
|
0c4ebd1e55 | ||
|
|
b920b6b45e | ||
|
|
71036b212b | ||
|
|
bfdbc118ba | ||
|
|
68bf4fe26d |
2
.github/workflows/test-and-release.yml
vendored
2
.github/workflows/test-and-release.yml
vendored
@@ -65,7 +65,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check increment result
|
- name: Check increment result
|
||||||
shell: bash
|
shell: bash
|
||||||
run: '[[ "$(date +%Y.%m)" == "$(echo "${{ steps.version-increment.outputs.VERSION }}" | cut -d "." -f 1-2)" ]]'
|
run: '[[ "$(date +%Y.%-m)" == "$(echo "${{ steps.version-increment.outputs.VERSION }}" | cut -d "." -f 1-2)" ]]'
|
||||||
|
|
||||||
test-action-yml: # integration testing
|
test-action-yml: # integration testing
|
||||||
needs:
|
needs:
|
||||||
|
|||||||
1
.shellcheckrc
Normal file
1
.shellcheckrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
external-sources=true
|
||||||
20
README.md
20
README.md
@@ -30,7 +30,7 @@ use the API mode:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Get next version
|
- name: Get next version
|
||||||
uses: reecetech/version-increment@2023.10.1
|
uses: reecetech/version-increment@2024.4.1
|
||||||
id: version
|
id: version
|
||||||
with:
|
with:
|
||||||
use_api: true
|
use_api: true
|
||||||
@@ -70,6 +70,22 @@ If the current latest normal version is not the current year and month, then the
|
|||||||
year and month digits will be
|
year and month digits will be
|
||||||
set to the current year and month, and the release digit will be reset to 1.
|
set to the current year and month, and the release digit will be reset to 1.
|
||||||
|
|
||||||
|
### Conventional Commits (semver with smarts) 💡
|
||||||
|
|
||||||
|
If you choose the conventional commits scheme, the action will parse the last commit message _(usually the merge commit)_ to determine
|
||||||
|
the increment type for a `semver` version.
|
||||||
|
|
||||||
|
The following increment types by keyword are supported:
|
||||||
|
- patch: build, chore, ci, docs, fix, perf, refactor, revert, style, test
|
||||||
|
- minor: feat
|
||||||
|
- major: any of the above keywords followed by a '!' character, or 'BREAKING CHANGE:' in commit body
|
||||||
|
|
||||||
|
If none of the keywords are detected, then the increment specified by the `increment` input will be used (defaults to patch).
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> You might like to _enforce_ conventional commits in the title of your pull requests to ensure that the merge commit has the correct
|
||||||
|
> information. Something like this action might be handy: https://github.com/marketplace/actions/conventional-commit-in-pull-requests
|
||||||
|
|
||||||
### Default branch vs. any other branch 🎋
|
### Default branch vs. any other branch 🎋
|
||||||
|
|
||||||
**Default branch**
|
**Default branch**
|
||||||
@@ -107,7 +123,7 @@ Examples:
|
|||||||
|
|
||||||
| name | description | required | default |
|
| name | description | required | default |
|
||||||
| :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- |
|
||||||
| scheme | The versioning scheme in-use, either `semver` or `calver` | No | `semver` |
|
| scheme | The versioning scheme in-use, either `semver`, `calver` or `conventional_commits` | No | `semver` |
|
||||||
| pep440 | Set to `true` for PEP440 compatibility of _pre-release_ versions by making use of the build metadata segment of semver, which maps to local version identifier in PEP440 | No | `false` |
|
| pep440 | Set to `true` for PEP440 compatibility of _pre-release_ versions by making use of the build metadata segment of semver, which maps to local version identifier in PEP440 | No | `false` |
|
||||||
| increment | The digit to increment, either `major`, `minor` or `patch`, ignored if `scheme` == `calver` | No | `patch` |
|
| increment | The digit to increment, either `major`, `minor` or `patch`, ignored if `scheme` == `calver` | No | `patch` |
|
||||||
| release_branch | Specify a non-default branch to use for the release tag (the one without -pre) | No | |
|
| release_branch | Specify a non-default branch to use for the release tag (the one without -pre) | No | |
|
||||||
|
|||||||
16
action.yml
16
action.yml
@@ -8,7 +8,14 @@ branding:
|
|||||||
|
|
||||||
inputs:
|
inputs:
|
||||||
scheme:
|
scheme:
|
||||||
description: 'Versioning scheme - semver, or, calver (defaults to semver)'
|
description: |
|
||||||
|
Versioning scheme - semver, calver or conventional_commits (defaults to semver).
|
||||||
|
|
||||||
|
`conventional_commits` Will parse the last commit message (e.g. the merge commit) to
|
||||||
|
determine the increment type, and supports the following increment types by keyword:
|
||||||
|
- patch (build, chore, ci, docs, fix, perf, refactor, revert, style, test)
|
||||||
|
- minor (feat)
|
||||||
|
- major (any of the above keywords followed by a '!' character, or 'BREAKING CHANGE:' in commit body)
|
||||||
required: false
|
required: false
|
||||||
default: 'semver'
|
default: 'semver'
|
||||||
pep440:
|
pep440:
|
||||||
@@ -19,6 +26,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Field to increment - major, minor, or, patch (defaults to patch)
|
Field to increment - major, minor, or, patch (defaults to patch)
|
||||||
|
|
||||||
|
If using the `conventional_commits` scheme, this is the default increment if the parsing of the merge commit fails to
|
||||||
|
find conventional commits information
|
||||||
|
|
||||||
Not applicable to `calver` scheme
|
Not applicable to `calver` scheme
|
||||||
required: false
|
required: false
|
||||||
default: 'patch'
|
default: 'patch'
|
||||||
@@ -36,14 +46,14 @@ outputs:
|
|||||||
description: 'Current normal version detected'
|
description: 'Current normal version detected'
|
||||||
value: ${{ steps.version-lookup.outputs.CURRENT_VERSION }}
|
value: ${{ steps.version-lookup.outputs.CURRENT_VERSION }}
|
||||||
current-v-version:
|
current-v-version:
|
||||||
description: 'Current normal version detected, prefixed with a `v` charatcter'
|
description: 'Current normal version detected, prefixed with a `v` character'
|
||||||
value: ${{ steps.version-lookup.outputs.CURRENT_V_VERSION }}
|
value: ${{ steps.version-lookup.outputs.CURRENT_V_VERSION }}
|
||||||
version:
|
version:
|
||||||
description: 'Incremented version calculated'
|
description: 'Incremented version calculated'
|
||||||
value: ${{ steps.version-increment.outputs.VERSION }}
|
value: ${{ steps.version-increment.outputs.VERSION }}
|
||||||
v-version:
|
v-version:
|
||||||
description: 'Incremented version calculated, prefixed with a `v` charatcter'
|
description: 'Incremented version calculated, prefixed with a `v` charatcter'
|
||||||
value: ${{ steps.version-increment.outputs.V_VERSION }}
|
value: ${{ steps.version-increment.outputs.V_VERSION }}
|
||||||
major-version:
|
major-version:
|
||||||
description: 'Major number of the incremented version'
|
description: 'Major number of the incremented version'
|
||||||
value: ${{ steps.version-increment.outputs.MAJOR_VERSION }}
|
value: ${{ steps.version-increment.outputs.MAJOR_VERSION }}
|
||||||
|
|||||||
13
shared.sh
13
shared.sh
@@ -11,13 +11,21 @@ pcre_master_ver='^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9
|
|||||||
pcre_allow_vprefix="^v{0,1}${pcre_master_ver:1}"
|
pcre_allow_vprefix="^v{0,1}${pcre_master_ver:1}"
|
||||||
pcre_old_calver='^(?P<major>0|[1-9]\d*)-0{0,1}(?P<minor>0|[0-9]\d*)-R(?P<patch>0|[1-9]\d*)$'
|
pcre_old_calver='^(?P<major>0|[1-9]\d*)-0{0,1}(?P<minor>0|[0-9]\d*)-R(?P<patch>0|[1-9]\d*)$'
|
||||||
|
|
||||||
|
##==----------------------------------------------------------------------------
|
||||||
|
## Conventional commit regexes
|
||||||
|
## see: https://www.conventionalcommits.org/en/v1.0.0/
|
||||||
|
|
||||||
|
pcre_conventional_commit_patch='^(build|chore|ci|docs|fix|perf|refactor|revert|style|test)(\([a-zA-Z0-9-]+\))?:\s.*'
|
||||||
|
pcre_conventional_commit_minor='^(feat)(\([a-zA-Z0-9-]+\))?:\s.*'
|
||||||
|
pcre_conventional_commit_breaking='^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-zA-Z0-9-]+\))?!:.*|BREAKING CHANGE:'
|
||||||
|
|
||||||
##==----------------------------------------------------------------------------
|
##==----------------------------------------------------------------------------
|
||||||
## Input validation
|
## Input validation
|
||||||
|
|
||||||
input_errors='false'
|
input_errors='false'
|
||||||
scheme="${scheme:-semver}"
|
scheme="${scheme:-semver}"
|
||||||
if [[ "${scheme}" != 'semver' && "${scheme}" != 'calver' ]] ; then
|
if [[ "${scheme}" != 'semver' && "${scheme}" != 'calver' && "${scheme}" != 'conventional_commits' ]] ; then
|
||||||
echo "🛑 Value of 'scheme' is not valid, choose from 'semver' or 'calver'" 1>&2
|
echo "🛑 Value of 'scheme' is not valid, choose from 'semver', 'calver' or 'conventional_commits" 1>&2
|
||||||
input_errors='true'
|
input_errors='true'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -40,7 +48,6 @@ if [[ "${use_api}" == 'true' ]] ; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
##==----------------------------------------------------------------------------
|
##==----------------------------------------------------------------------------
|
||||||
## MacOS compatibility - for local testing
|
## MacOS compatibility - for local testing
|
||||||
|
|
||||||
|
|||||||
@@ -272,3 +272,131 @@ function init_repo {
|
|||||||
[[ "$output" = *"PRE_RELEASE_LABEL=pre.${short_ref}"* ]] &&
|
[[ "$output" = *"PRE_RELEASE_LABEL=pre.${short_ref}"* ]] &&
|
||||||
[[ "$output" = *"VERSION=$(date +%Y.%-m.1)+pre.${short_ref}"* ]]
|
[[ "$output" = *"VERSION=$(date +%Y.%-m.1)+pre.${short_ref}"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "increments the patch version after a fix commit (conventional commits)" {
|
||||||
|
init_repo
|
||||||
|
|
||||||
|
export current_version=1.2.3
|
||||||
|
export scheme="conventional_commits"
|
||||||
|
|
||||||
|
echo "fix: something" > fix.txt
|
||||||
|
git add fix.txt
|
||||||
|
git commit -m "fix: something"
|
||||||
|
|
||||||
|
run ../../version-increment.sh
|
||||||
|
|
||||||
|
print_run_info
|
||||||
|
[ "$status" -eq 0 ] &&
|
||||||
|
[[ "$output" = *"VERSION=1.2.4"* ]]
|
||||||
|
[[ "$output" != *"No conventional commit found"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@test "increments the patch version after a scoped fix commit (conventional commits)" {
|
||||||
|
init_repo
|
||||||
|
|
||||||
|
export current_version=1.2.3
|
||||||
|
export scheme="conventional_commits"
|
||||||
|
|
||||||
|
echo "fix: something" > fix.txt
|
||||||
|
git add fix.txt
|
||||||
|
git commit -m "fix(api): something"
|
||||||
|
|
||||||
|
run ../../version-increment.sh
|
||||||
|
|
||||||
|
print_run_info
|
||||||
|
[ "$status" -eq 0 ] &&
|
||||||
|
[[ "$output" = *"VERSION=1.2.4"* ]]
|
||||||
|
[[ "$output" != *"No conventional commit found"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "increments the major version after a breaking fix commit (conventional commits)" {
|
||||||
|
init_repo
|
||||||
|
|
||||||
|
export current_version=1.2.3
|
||||||
|
export scheme="conventional_commits"
|
||||||
|
|
||||||
|
echo "fix: breaking something" > fix.txt
|
||||||
|
git add fix.txt
|
||||||
|
git commit -m "fix!: something"
|
||||||
|
|
||||||
|
run ../../version-increment.sh
|
||||||
|
|
||||||
|
print_run_info
|
||||||
|
[ "$status" -eq 0 ] &&
|
||||||
|
[[ "$output" = *"VERSION=2.0.0"* ]]
|
||||||
|
[[ "$output" != *"No conventional commit found"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "increments the minor version after a feat commit (conventional commits)" {
|
||||||
|
init_repo
|
||||||
|
|
||||||
|
export current_version=1.2.3
|
||||||
|
export scheme="conventional_commits"
|
||||||
|
|
||||||
|
echo "new feature" > feat.txt
|
||||||
|
git add feat.txt
|
||||||
|
git commit -m "feat: something"
|
||||||
|
|
||||||
|
run ../../version-increment.sh
|
||||||
|
|
||||||
|
print_run_info
|
||||||
|
[ "$status" -eq 0 ] &&
|
||||||
|
[[ "$output" = *"VERSION=1.3.0"* ]]
|
||||||
|
[[ "$output" != *"No conventional commit found"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "increments the major version after a breaking feat commit (conventional commits)" {
|
||||||
|
init_repo
|
||||||
|
|
||||||
|
export current_version=1.2.3
|
||||||
|
export scheme="conventional_commits"
|
||||||
|
|
||||||
|
echo "breaking new feature" > feat.txt
|
||||||
|
git add feat.txt
|
||||||
|
git commit -m "feat!: something"
|
||||||
|
|
||||||
|
run ../../version-increment.sh
|
||||||
|
|
||||||
|
print_run_info
|
||||||
|
[ "$status" -eq 0 ] &&
|
||||||
|
[[ "$output" = *"VERSION=2.0.0"* ]]
|
||||||
|
[[ "$output" != *"No conventional commit found"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "increments the major version after a breaking change in the commit body (conventional commits)" {
|
||||||
|
init_repo
|
||||||
|
|
||||||
|
export current_version=1.2.3
|
||||||
|
export scheme="conventional_commits"
|
||||||
|
|
||||||
|
echo "breaking new fix" > feat.txt
|
||||||
|
git add feat.txt
|
||||||
|
git commit -m "Fix: something
|
||||||
|
BREAKING CHANGE: really important"
|
||||||
|
|
||||||
|
run ../../version-increment.sh
|
||||||
|
|
||||||
|
print_run_info
|
||||||
|
[ "$status" -eq 0 ] &&
|
||||||
|
[[ "$output" = *"VERSION=2.0.0"* ]]
|
||||||
|
[[ "$output" != *"No conventional commit found"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "increments the patch version by default if no conventional commits found and enabled (conventional commits)" {
|
||||||
|
init_repo
|
||||||
|
|
||||||
|
export current_version=1.2.3
|
||||||
|
export scheme="conventional_commits"
|
||||||
|
|
||||||
|
echo "some new change" > feat.txt
|
||||||
|
git add feat.txt
|
||||||
|
git commit -m "new change"
|
||||||
|
|
||||||
|
run ../../version-increment.sh
|
||||||
|
|
||||||
|
print_run_info
|
||||||
|
[ "$status" -eq 0 ] &&
|
||||||
|
[[ "$output" = *"VERSION=1.2.4"* ]]
|
||||||
|
[[ "$output" = *"No conventional commit found"* ]]
|
||||||
|
}
|
||||||
|
|||||||
@@ -110,18 +110,6 @@ function init_repo {
|
|||||||
[[ "$output" = *"CURRENT_VERSION=$(date '+%Y.%-m.0')"* ]]
|
[[ "$output" = *"CURRENT_VERSION=$(date '+%Y.%-m.0')"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "converts from older calver scheme automatically" {
|
|
||||||
init_repo
|
|
||||||
|
|
||||||
git tag 2020-09-R2
|
|
||||||
|
|
||||||
run ../../version-lookup.sh
|
|
||||||
|
|
||||||
print_run_info
|
|
||||||
[ "$status" -eq 0 ] &&
|
|
||||||
[[ "$output" = *"CURRENT_VERSION=2020.9.2"* ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "strips v from the version" {
|
@test "strips v from the version" {
|
||||||
init_repo
|
init_repo
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ fi
|
|||||||
default_branch='main'
|
default_branch='main'
|
||||||
# use release_branch if not empty
|
# use release_branch if not empty
|
||||||
if [[ -n "${release_branch:-}" ]] ; then
|
if [[ -n "${release_branch:-}" ]] ; then
|
||||||
default_branch="${release_branch}"
|
default_branch="${release_branch}"
|
||||||
elif [[ -z "${BATS_VERSION:-}" ]] ; then
|
elif [[ -z "${BATS_VERSION:-}" ]] ; then
|
||||||
# if we're _not_ testing, then _actually_ check the origin
|
# if we're _not_ testing, then _actually_ check the origin
|
||||||
if [[ "${use_api:-}" == 'true' ]] ; then
|
if [[ "${use_api:-}" == 'true' ]] ; then
|
||||||
@@ -48,6 +48,7 @@ elif [[ -z "${BATS_VERSION:-}" ]] ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
current_ref="${GITHUB_REF:-}"
|
current_ref="${GITHUB_REF:-}"
|
||||||
|
git_commit_sha=${GITHUB_SHA:-}
|
||||||
|
|
||||||
if [[ "${use_api:-}" == 'true' ]] ; then
|
if [[ "${use_api:-}" == 'true' ]] ; then
|
||||||
# because we cannot use `rev-parse` with the API, we'll take a punt that 9 characters is enough for uniqueness
|
# because we cannot use `rev-parse` with the API, we'll take a punt that 9 characters is enough for uniqueness
|
||||||
@@ -55,7 +56,32 @@ if [[ "${use_api:-}" == 'true' ]] ; then
|
|||||||
git_commit="$(echo "${GITHUB_SHA:0:9}" | sed 's/0*//')" # Also, trim leading zeros, because semver doesn't allow that in
|
git_commit="$(echo "${GITHUB_SHA:0:9}" | sed 's/0*//')" # Also, trim leading zeros, because semver doesn't allow that in
|
||||||
else # the 'pre-release version' part, but we can't use the + char
|
else # the 'pre-release version' part, but we can't use the + char
|
||||||
git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # to make it 'build metadata' as that's not supported in K8s
|
git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # to make it 'build metadata' as that's not supported in K8s
|
||||||
fi # labels
|
git_commit_sha="$(git rev-parse --short HEAD)" # labels
|
||||||
|
fi
|
||||||
|
|
||||||
|
##==----------------------------------------------------------------------------
|
||||||
|
## Conventional commits
|
||||||
|
if [[ "${scheme}" == 'conventional_commits' ]] ; then
|
||||||
|
# Get message from given commit
|
||||||
|
commit_message=$(git log -1 --pretty=format:%B "${git_commit_sha}")
|
||||||
|
|
||||||
|
# Check commit message header
|
||||||
|
found_match='false'
|
||||||
|
if [[ -n "$(echo "${commit_message}" | ${grep} -P "${pcre_conventional_commit_breaking}")" ]] ; then
|
||||||
|
increment='major'
|
||||||
|
found_match='true'
|
||||||
|
elif [[ -n "$(echo "${commit_message}" | ${grep} -P "${pcre_conventional_commit_minor}")" ]] ; then
|
||||||
|
increment='minor'
|
||||||
|
found_match='true'
|
||||||
|
elif [[ -n "$(echo "${commit_message}" | ${grep} -P "${pcre_conventional_commit_patch}")" ]] ; then
|
||||||
|
increment='patch'
|
||||||
|
found_match='true'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${found_match}" == 'false' ]] ; then
|
||||||
|
echo "⚠️ No conventional commit found, defaulting to ${increment} increment" 1>&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
##==----------------------------------------------------------------------------
|
##==----------------------------------------------------------------------------
|
||||||
## Version increment
|
## Version increment
|
||||||
|
|||||||
@@ -10,18 +10,6 @@ if [[ "${input_errors}" == 'true' ]] ; then
|
|||||||
exit 8
|
exit 8
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##==----------------------------------------------------------------------------
|
|
||||||
## MacOS compatibility - for local testing
|
|
||||||
|
|
||||||
export grep="grep"
|
|
||||||
if [[ "$(uname)" == "Darwin" ]] ; then
|
|
||||||
export grep="ggrep"
|
|
||||||
if ! grep --version 1>/dev/null ; then
|
|
||||||
echo "🛑 GNU grep not installed, try brew install coreutils" 1>&2
|
|
||||||
exit 9
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
##==----------------------------------------------------------------------------
|
##==----------------------------------------------------------------------------
|
||||||
## Get tags from GitHub repo
|
## Get tags from GitHub repo
|
||||||
|
|
||||||
@@ -53,21 +41,12 @@ else
|
|||||||
)"
|
)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# support transition from an old reecetech calver style (yyyy-mm-Rr, where R is the literal `R`, and r is the nth release for the month)
|
|
||||||
if [[ -z "${current_version:-}" ]] ; then
|
|
||||||
current_version="$(git tag -l | { ${grep} -P "${pcre_old_calver}" || true; } | sort -V | tail -n 1)"
|
|
||||||
if [[ -n "${current_version:-}" ]] ; then
|
|
||||||
# convert - to . and drop leading zeros & the R
|
|
||||||
current_version="$(echo "${current_version}" | sed -r 's/^([0-9]+)-0{0,1}([0-9]+)-R0{0,1}([0-9]+)$/\1.\2.\3/')"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# handle no version detected - start versioning!
|
# handle no version detected - start versioning!
|
||||||
if [[ -z "${current_version:-}" ]] ; then
|
if [[ -z "${current_version:-}" ]] ; then
|
||||||
echo "⚠️ No previous release version identified in git tags"
|
echo "⚠️ No previous release version identified in git tags"
|
||||||
# brand new repo! (probably)
|
# brand new repo! (probably)
|
||||||
case "${scheme}" in
|
case "${scheme}" in
|
||||||
semver)
|
semver | conventional_commits)
|
||||||
current_version="0.0.0"
|
current_version="0.0.0"
|
||||||
;;
|
;;
|
||||||
calver)
|
calver)
|
||||||
|
|||||||
Reference in New Issue
Block a user