-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add CI skip command check template (#74)
* Add check-skip template Signed-off-by: Conor MacBride <conor@macbride.me> * Add check-skip documentation Signed-off-by: Conor MacBride <conor@macbride.me> * Set as executable Signed-off-by: Conor MacBride <conor@macbride.me> * Bash displayName to name Signed-off-by: Conor MacBride <conor@macbride.me> * Only check on PR trigger Signed-off-by: Conor MacBride <conor@macbride.me>
- Loading branch information
1 parent
b273771
commit 14d3f7d
Showing
5 changed files
with
245 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#!/usr/bin/env bash | ||
SKIP_VAR_NAME="found" # variable name to set in Azure job | ||
|
||
help () { | ||
echo "Search for a skip command in the commit message and set Azure variable." | ||
echo | ||
echo "Usage: check-skip.sh [merge_commit_message]" | ||
echo | ||
echo "If merge_commit_message is not provided as an argument, its value" | ||
echo "will be taken from a COMMIT_MESSAGE environment variable." | ||
echo "An alternative list of skip commands can be specified in a" | ||
echo "SKIP_COMMANDS environment variable as space separated commands" | ||
echo "with commands containing spaces inside escaped double quotes." | ||
echo | ||
} | ||
|
||
require_argument () { | ||
if [[ -z $2 ]]; then | ||
echo "Argument '$1' must be given." 1>&2 | ||
exit 1 | ||
fi | ||
} | ||
|
||
get_skip_commands () { | ||
if [[ -n $SKIP_COMMANDS ]]; then | ||
# "\"[skip ci]\" \"skip tests\" pass" -> "[skip ci]" "skip tests" "pass" | ||
if ! declare -a -g "SKIP_COMMANDS=($SKIP_COMMANDS)"; then | ||
echo "Bash version 4.2 or later required for custom skip commands." 1>&2 | ||
exit 1 | ||
fi | ||
printf "Using custom skip commands:" | ||
else | ||
SKIP_COMMANDS=( | ||
"[skip ci]" "[ci skip]" | ||
"skip-checks: true" "skip-checks:true" | ||
"[skip azurepipelines]" "[azurepipelines skip]" | ||
"[skip azpipelines]" "[azpipelines skip]" | ||
"[skip azp]" "[azp skip]" | ||
"***NO_CI***" | ||
) | ||
# https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands | ||
printf "Using default skip commands:" | ||
fi | ||
for c in "${SKIP_COMMANDS[@]}"; do | ||
printf " '%s'" "$c" | ||
done | ||
printf "\n" | ||
} | ||
|
||
get_merge_commit_message () { | ||
if [[ -n "$1" ]]; then | ||
MERGE_MSG=$1 | ||
elif [[ -n "$COMMIT_MESSAGE" ]]; then | ||
MERGE_MSG=$COMMIT_MESSAGE | ||
else | ||
help | ||
exit 1 | ||
fi | ||
echo "Merge commit being tested: '$MERGE_MSG'" | ||
} | ||
|
||
get_commit_hash () { | ||
require_argument merge_commit_message "$1" | ||
if ! [[ $1 =~ ^Merge[[:space:]][0-9a-fA-F]+[[:space:]]into[[:space:]][0-9a-fA-F]+$ ]]; then | ||
echo "Expected commit message to be of form 'Merge HEX into HEX'." 1>&2 | ||
echo "Please open an issue: https://github.com/OpenAstronomy/azure-pipelines-templates/issues" 1>&2 | ||
exit 1 | ||
fi | ||
COMMIT_HASH=$(echo "$1" | awk '{print $2}') | ||
echo "Latest commit hash in PR branch: '$COMMIT_HASH'" | ||
} | ||
|
||
get_commit_message () { | ||
require_argument commit_hash "$1" | ||
MSG=$(git log --format=%B -n 1 "$1") | ||
if [ $? -ne 0 ]; then | ||
echo "Error running: git log --format=%B -n 1 $1" 1>&2 | ||
exit 1 | ||
fi | ||
MSG=$(echo "$MSG" | head -1) | ||
echo "Message being searched for skip commands: '$MSG'" | ||
} | ||
|
||
set_skip_var () { | ||
if ! [[ "true false" =~ (^|[[:space:]])$1($|[[:space:]]) ]]; then | ||
echo "Argument must be 'true' or 'false', got '$1'." 1>&2 | ||
exit 1 | ||
fi | ||
echo "##vso[task.setvariable variable=$SKIP_VAR_NAME;isOutput=true]$1" | ||
} | ||
|
||
search_for_skip () { | ||
require_argument message "$1" | ||
for c in "${SKIP_COMMANDS[@]}"; do | ||
if [[ "$1" =~ "$c" ]]; then | ||
echo "Found command '$c' in message." | ||
set_skip_var true | ||
exit 0 | ||
fi | ||
done | ||
echo "No skips commands found in message." | ||
set_skip_var false | ||
} | ||
|
||
get_merge_commit_message "$1" | ||
get_commit_hash "$MERGE_MSG" | ||
get_commit_message "$COMMIT_HASH" | ||
get_skip_commands | ||
search_for_skip "$MSG" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
parameters: | ||
- name: commands | ||
type: string | ||
default: '' | ||
|
||
jobs: | ||
- job: check_skip | ||
steps: | ||
- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: | ||
- checkout: self | ||
path: s/self | ||
- checkout: OpenAstronomy | ||
path: s/azure-pipelines-templates | ||
- bash: $(Pipeline.Workspace)/s/azure-pipelines-templates/check-skip.sh | ||
workingDirectory: $(Pipeline.Workspace)/s/self | ||
name: search | ||
env: | ||
COMMIT_MESSAGE: $(Build.SourceVersionMessage) | ||
${{ if parameters.commands }}: | ||
SKIP_COMMANDS: ${{ parameters.commands }} | ||
- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}: | ||
- bash: echo "##vso[task.setvariable variable=found;isOutput=true]false" | ||
name: search |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
|
||
CI skip command check template | ||
============================== | ||
|
||
This template provides a job which parses the commit message of the pull | ||
request, and if it contains a CI skip command such as ``[skip ci]`` it sets | ||
a variable in the Azure Pipelines run. This variable can be used as a | ||
condition on subsequent stages of the run, such that using a skip command | ||
reduces the amount of building and testing. | ||
|
||
For a CI skip command to be recognised for a job, the latest commit to the | ||
pull request branch that triggered the Azure Pipelines run must have a | ||
commit message that contains a recognised CI skip command in its first line. | ||
Recognised commands include ``[skip ci]`` and ``[ci skip]``. | ||
See :ref:`custom-skip-commands` for more details. | ||
|
||
Basic setup | ||
----------- | ||
|
||
Firstly, ensure you load the templates under the ``OpenAstronomy`` | ||
namespace as described in :doc:`common`. | ||
The following code shows how to place the job within a stage. | ||
|
||
.. code:: yaml | ||
stages: | ||
- stage: StageOne | ||
jobs: | ||
- template: check-skip.yml@OpenAstronomy | ||
The template must be called as a job within a stage prior to | ||
the stages you want to conditionally skip. | ||
|
||
Applying conditions to pipeline stages | ||
-------------------------------------- | ||
|
||
The job provided by this template creates a variable in the Azure Pipelines run. | ||
This variable is accessed at | ||
``dependencies.STAGE_NAME.outputs['check_skip.search.found']`` | ||
where ``STAGE_NAME`` should be replaced with the name of the stage the template | ||
was used within. | ||
|
||
It will have a string value of either ``'true'`` or ``'false'``. It will be | ||
``'true'`` if a skip command was found in the commit message and ``'false'`` | ||
otherwise. | ||
|
||
This variable can be used to apply a condition to subsequent stages of the | ||
run, for example, | ||
``and(succeeded(), ne(dependencies.Setup.outputs['check_skip.search.found'], 'true'))``. | ||
|
||
Example | ||
------- | ||
|
||
The following code provides an example of how to configure the stages | ||
section of your ``azure-pipelines.yml`` file using this template. | ||
Note that you will also need to make sure you first load the templates as | ||
described in :doc:`common`. | ||
|
||
.. code:: yaml | ||
stages: | ||
- stage: StageOneTests | ||
displayName: Basic Tests | ||
jobs: | ||
- template: check-skip.yml@OpenAstronomy | ||
- template: run-tox-env.yml@OpenAstronomy | ||
envs: | ||
- linux: py39 | ||
- stage: StageTwoTests | ||
displayName: Detailed Tests | ||
condition: and(succeeded(), ne(dependencies.StageOneTests.outputs['check_skip.search.found'], 'true')) | ||
jobs: | ||
- template: run-tox-env.yml@OpenAstronomy | ||
envs: | ||
- macos: py39 | ||
- windows: py39 | ||
In this example, the *Basic Tests* stage will always run, however, if a skip | ||
command is in the commit message the *Detailed Tests* stage will not run. | ||
As this template is independent of the other OpenAstronomy templates, | ||
the stages conditions are applied to do not need to run jobs defined | ||
using ``run-tox-env.yml``. | ||
|
||
.. _custom-skip-commands: | ||
|
||
Custom skip commands | ||
-------------------- | ||
|
||
By default, the list of recognised skip commands are taken from the `Azure Pipelines documentation | ||
<https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands?view=azure-devops&tabs=yaml#how-do-i-avoid-triggering-a-ci-build-when-the-script-pushes>`__. | ||
This list includes ``[skip ci]`` and ``[ci skip]`` among others. | ||
|
||
This default list can be replaced as shown in the following code. | ||
|
||
.. code:: yaml | ||
stages: | ||
- stage: StageOne | ||
jobs: | ||
- template: check-skip.yml@OpenAstronomy | ||
commands: '"[skip ci]" "[ci skip]" noci' | ||
This will configure the check to only recognise ``[skip ci]``, ``[ci skip]`` | ||
and ``noci`` as valid skip commands. | ||
The value of ``commands`` must be a string of space separated skip commands, | ||
with commands containing spaces inside double quotes. | ||
Bash version 4.2 or above is required if specifying custom skip commands. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters