66 lines
2.4 KiB
Python
66 lines
2.4 KiB
Python
import argparse
|
|
import os
|
|
import subprocess
|
|
|
|
|
|
def get_commit_message():
|
|
"""Retrieve the commit message."""
|
|
build_source_version_message = os.environ["BUILD_SOURCEVERSIONMESSAGE"]
|
|
|
|
if os.environ["BUILD_REASON"] == "PullRequest":
|
|
# By default pull requests use refs/pull/PULL_ID/merge as the source branch
|
|
# which has a "Merge ID into ID" as a commit message. The latest commit
|
|
# message is the second to last commit
|
|
commit_id = build_source_version_message.split()[1]
|
|
git_cmd = ["git", "log", commit_id, "-1", "--pretty=%B"]
|
|
commit_message = subprocess.run(
|
|
git_cmd, capture_output=True, text=True
|
|
).stdout.strip()
|
|
else:
|
|
commit_message = build_source_version_message
|
|
|
|
# Sanitize the commit message to avoid introducing a vulnerability: a PR
|
|
# submitter could include the "##vso" special marker in their commit
|
|
# message to attempt to obfuscate the injection of arbitrary commands in
|
|
# the Azure pipeline.
|
|
#
|
|
# This can be a problem if the PR reviewers do not pay close enough
|
|
# attention to the full commit message prior to clicking the merge button
|
|
# and as a result make the inject code run in a protected branch with
|
|
# elevated access to CI secrets. On a protected branch, Azure
|
|
# already sanitizes `BUILD_SOURCEVERSIONMESSAGE`, but the message
|
|
# will still be sanitized here out of precaution.
|
|
commit_message = commit_message.replace("##vso", "..vso")
|
|
|
|
return commit_message
|
|
|
|
|
|
def parsed_args():
|
|
parser = argparse.ArgumentParser(
|
|
description=(
|
|
"Show commit message that triggered the build in Azure DevOps pipeline"
|
|
)
|
|
)
|
|
parser.add_argument(
|
|
"--only-show-message",
|
|
action="store_true",
|
|
default=False,
|
|
help=(
|
|
"Only print commit message. Useful for direct use in scripts rather than"
|
|
" setting output variable of the Azure job"
|
|
),
|
|
)
|
|
return parser.parse_args()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
args = parsed_args()
|
|
commit_message = get_commit_message()
|
|
|
|
if args.only_show_message:
|
|
print(commit_message)
|
|
else:
|
|
# set the environment variable to be propagated to other steps
|
|
print(f"##vso[task.setvariable variable=message;isOutput=true]{commit_message}")
|
|
print(f"commit message: {commit_message}") # helps debugging
|