Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux with Taskcluster Notifier #135

Merged
merged 63 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
ac10bf0
add slack hook
sarinali Jun 14, 2024
3ecb2bb
add scripts
sarinali Jun 14, 2024
407cc4a
fix yml
sarinali Jun 14, 2024
aff42ee
edit yml
sarinali Jun 17, 2024
34d38f6
fix yml
sarinali Jun 17, 2024
f84d9f4
trying to fix ci schema
sarinali Jun 17, 2024
147c74f
add transforms
sarinali Jun 17, 2024
c665651
fix yaml
sarinali Jun 19, 2024
fbd4a48
merge main in
sarinali Jun 21, 2024
086dfe7
merge
sarinali Jun 24, 2024
2440296
add notify block
sarinali Jun 26, 2024
b651188
update taskcluster version
sarinali Jun 26, 2024
3e2ba7d
change ci taskcluster version
sarinali Jun 26, 2024
2c01ac1
update taskcluster version
sarinali Jun 27, 2024
a74112e
added max run time back
sarinali Jun 27, 2024
8412d7b
change hash
sarinali Jun 27, 2024
3262147
update taskcluster version
sarinali Jun 27, 2024
902b061
remove lines from taskcluster.yml
sarinali Jun 28, 2024
2913f71
add new slack channel
sarinali Jul 2, 2024
2e3016e
change slack channel
sarinali Jul 2, 2024
fd9800e
merge changes in
sarinali Jul 2, 2024
cbcb2e3
change channel
sarinali Jul 3, 2024
f6e13f4
merge changes in
sarinali Jul 3, 2024
d6c2368
new channel
sarinali Jul 3, 2024
90e7dea
delete extra dep
sarinali Jul 3, 2024
732bc86
trying something
sarinali Jul 3, 2024
282817a
add some commands back
sarinali Jul 3, 2024
eb0d40e
add extra route
sarinali Jul 3, 2024
9ff8c98
added slack block
sarinali Jul 4, 2024
e5fb3cd
change slack block text
sarinali Jul 4, 2024
0b1b310
change the message
sarinali Jul 4, 2024
f70edc3
change task notify location:
sarinali Jul 4, 2024
ced214b
add block back
sarinali Jul 4, 2024
8aeb9d2
echo the current path
sarinali Jul 9, 2024
1550d0c
add the taskid
sarinali Jul 9, 2024
da0fd21
merge and add some line
sarinali Jul 9, 2024
6f8d956
changing the status type
sarinali Jul 9, 2024
1005e41
merge changes in
sarinali Jul 11, 2024
9bca386
trying log options
sarinali Jul 11, 2024
816dc3a
update gitignore
sarinali Jul 12, 2024
7f3c834
added some slack block formatting
sarinali Jul 12, 2024
79e8726
change line
sarinali Jul 12, 2024
2ec910f
see metadata
sarinali Jul 12, 2024
c536499
add commit hash
sarinali Jul 12, 2024
cbc4c17
add source
sarinali Jul 12, 2024
70d48c1
merge changes in
sarinali Jul 18, 2024
8a5db5c
change the task name
sarinali Jul 18, 2024
8d523ca
add command
sarinali Jul 18, 2024
ac44a12
remove some files
sarinali Jul 18, 2024
27287e8
Merge branch 'main' into sl/ci-slack-notifier
ben-c-at-moz Jul 18, 2024
7a87dcc
merge changes in
sarinali Jul 19, 2024
0c9c6c1
change link
sarinali Jul 19, 2024
c9d9c8c
merge changes in
sarinali Jul 23, 2024
e25e607
add commit back
sarinali Jul 23, 2024
102331b
make sure works
sarinali Jul 23, 2024
ba17cfd
change line back
sarinali Jul 23, 2024
bf5975c
cherry pick changes over
sarinali Jul 24, 2024
b7c975e
merge changes in
sarinali Jul 25, 2024
ed2f32c
update gha flow and tests
ben-c-at-moz Jul 26, 2024
39b12e4
merge changes in
sarinali Jul 29, 2024
802f93c
merge changes in
sarinali Jul 29, 2024
330af57
changes not persisting
sarinali Jul 29, 2024
c7fdbce
merge remote
sarinali Jul 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
pip3 install 'pipenv==2023.11.15';
pip3 install 'ruff>=0.4.8,<0.5';
bash collect_executables.sh;
sleep 3;
rm ./pyproject.toml;
mv ./ci_pyproject.toml ./pyproject.toml;
pipenv install;
Expand Down Expand Up @@ -48,6 +49,7 @@ jobs:
pip3 install 'pipenv==2023.11.15';
pip3 install 'ruff>=0.4.8,<0.5';
bash collect_executables.sh;
sleep 3;
rm ./pyproject.toml;
mv ./ci_pyproject.toml ./pyproject.toml;
pipenv install;
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ env
*.zip
*.gz
*.7z
*.xml
test.sh
file[0-9]*.txt

Expand Down
7 changes: 3 additions & 4 deletions .taskcluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ tasks:
${normProjectUpper}_HEAD_REF: '${short_head_ref}'
${normProjectUpper}_HEAD_REV: '${head_sha}'
${normProjectUpper}_REPOSITORY_TYPE: git
${normProjectUpper}_PIP_REQUIREMENTS: taskcluster/requirements.txt
REPOSITORIES:
$json:
${normProject}: ${normProject}
Expand All @@ -203,7 +202,7 @@ tasks:
features:
taskclusterProxy: true

image: mozillareleases/taskgraph:decision-c4ac262880970ca484105929e02dd12f00214d5f2603ab6ce4c0d17de5cd0280@sha256:2dd667994aa13fccdcdcede85c570a5eb4a5247e42875a9e95a135ef774ee469
image: mozillareleases/taskgraph:decision-v9.0.0@sha256:e56c7e5cd467c2ce497c344b358f68cc84a4f73f3422e507a97b397d4e617fbd
maxRunTime: 1800

command:
Expand All @@ -220,11 +219,11 @@ tasks:
cd /builds/worker/checkouts/src &&
ln -s /builds/worker/artifacts artifacts &&
pip3 install -r requirements/base.txt &&
~/.local/bin/taskgraph action-callback
taskgraph action-callback
else: >
cd /builds/worker/checkouts/src &&
ln -s /builds/worker/artifacts artifacts &&
~/.local/bin/taskgraph decision
taskgraph decision
--pushlog-id='0'
--pushdate='0'
--project='${project}'
Expand Down
2 changes: 1 addition & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ requests = "*"
pytest-xdist = "*"
pytest-html = "*"
pypom = "*"
taskcluster-taskgraph = "==9.0.0"
jsonpath-ng = "*"
pillow = "*"
pyfxa = "*"
Expand All @@ -24,4 +25,3 @@ werkzeug = "*"
selenium-wire = "*"
pdoc = "*"
pytest-variables = "*"
taskcluster-taskgraph = "*"
71 changes: 69 additions & 2 deletions taskcluster/kinds/run-smoke-tests/kind.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
---
transforms:
- fx_desktop_qa_automation_taskgraph.transforms.smoketest:transforms
- taskgraph.transforms.notify:transforms

task-defaults:
label: "Smoke Tests"
description: "Runs Smoke Tests and Notifies Slack"
worker-type: t-linux-wayland
worker:
max-run-time: 1800
artifacts:
- name: public/results
path: checkouts/vcs/artifacts
type: directory
routes:
- notify.slack-channel.C07AHPJ525V.on-resolved
scopes:
- queue:route:notify.slack-channel.C07AHPJ525V # notify mobile-alerts-sandbox on failure
- notify:slack-channel:C07AHPJ525V

tasks:
linux:
Expand All @@ -24,4 +31,64 @@ tasks:
./collect_executables.sh;
mv ./ci_pyproject.toml ./pyproject.toml;
pipenv install;
pipenv run pytest --fx-executable ./firefox/firefox -n 4 .
pipenv run pytest --fx-executable ./firefox/firefox -n 4 .
notify:
recipients:
- type: slack-channel
channel-id: C07AHPJ525V
status-type: on-defined
content:
slack:
blocks: [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "firefox-desktop :firefox: ${task.metadata.name}\n "
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Task*: <https://firefox-ci-tc.services.mozilla.com/tasks/${status.taskId}|Taskcluster>"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Owner*: ${task.metadata.owner}"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Commit*: <${task.metadata.source}>"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Test Summary*: <https://firefoxci.taskcluster-artifacts.net/${status.taskId}/0/public/results/report.html?sort=result> :debug:"
}
},
{
"type": "divider"
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": ":testops-notify: created by Desktop QA Test Engineering"
}
]
}
]
text: "{task[name]} with id $taskId has finished!"
2 changes: 1 addition & 1 deletion taskcluster/requirements.in
Original file line number Diff line number Diff line change
@@ -1 +1 @@
taskcluster-taskgraph>=7.0.0
taskcluster-taskgraph>=9.0.0
12 changes: 6 additions & 6 deletions taskcluster/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --generate-hashes
# pip-compile --generate-hashes taskcluster/requirements.in
#
appdirs==1.4.4 \
--hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41 \
Expand Down Expand Up @@ -267,10 +267,10 @@ slugid==2.0.0 \
--hash=sha256:a950d98b72691178bdd4d6c52743c4a2aa039207cf7a97d71060a111ff9ba297 \
--hash=sha256:aec8b0e01c4ad32e38e12d609eab3ec912fd129aaf6b2ded0199b56a5f8fd67c
# via taskcluster-taskgraph
taskcluster-taskgraph==7.0.0 \
--hash=sha256:1553e1ae7709296643701faedafc8fc1e4a9b546f2ed270445ebd025d74101bf \
--hash=sha256:9fa7fb1ccbf1b2e607117d599de3ea82fff71dbf732124216ac6c16bf19c3127
# via -r requirements.in
taskcluster-taskgraph==9.0.0 \
--hash=sha256:306366c70da7353cc198406a36630b28ecc77ded32f7e4ca0187913d56c40713 \
--hash=sha256:3ebc1a07c31168c19159e71507341b40fc33ae3e652c7c80d8871904855021d1
# via -r taskcluster/requirements.in
taskcluster-urls==13.0.1 \
--hash=sha256:5e25e7e6818e8877178b175ff43d2e6548afad72694aa125f404a7329ece0973 \
--hash=sha256:b25e122ecec249c4299ac7b20b08db76e3e2025bdaeb699a9d444556de5fd367 \
Expand Down
194 changes: 194 additions & 0 deletions taskcluster/scripts/slack_notifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#!/usr/bin/env python3

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
This module provides functionalities for sending notifications to Slack channels, specifically designed for use in automated testing and release processes. It includes capabilities for sending both success and error notifications with customizable message templates. The module leverages Taskcluster for notification services and integrates with Slack's API to deliver real-time updates.

Key Features:
- SLACK_SUCCESS_MESSAGE_TEMPLATE: A predefined template for formatting success messages to be sent to Slack. This template includes placeholders for dynamic content such as product version and release details.
- SLACK_ERROR_MESSAGE_TEMPLATE: A template for error messages, used to notify about failures or issues in automated processes, particularly with TestRail API interactions.
- send_slack_notification: A function that sends a Slack notification based on a provided template and value dictionary. It handles the construction of the message payload and interfaces with Taskcluster's Slack notification service.
- get_taskcluster_options: Retrieves configuration options for Taskcluster based on the current runtime environment, ensuring appropriate setup for notification delivery.
- send_error_notification: A higher-level function that formats and sends error notifications to a specified Slack channel.
- send_success_notification: Similarly, this function sends success notifications to a specified Slack channel, using the success message template.

Usage:
The module is intended to be integrated into automated testing and release workflows, where Slack notifications are required to report the status of various processes, such as test executions or release milestones.

Required Values for Notifications:

These values are required when calling the `send_success_notification` and `send_slack_notification` functions.
They must be passed as an object with the following keys and their respective values.

Required Keys and Expected Values:
- RELEASE_TYPE: <string> Release Type or Stage (e.g., Alpha, Beta, RC).
- RELEASE_VERSION: <string> Release Version from versions.txt (e.g., '124.0b5').
- SHIPPING_PRODUCT: <string> Release Tag Name (e.g., fennec, focus).
- TESTRAIL_PROJECT_ID: <int> Project ID for TestRail Project (e.g., Fenix Browser).
- TESTRAIL_PRODUCT_TYPE: <string> Name for the official release product (e.g., Firefox, not fennec).

These values are used as arguments for `success_values` and `values` when calling the respective functions.

Example Usage:

success_values = {
"RELEASE_TYPE": "Beta",
"RELEASE_VERSION": "124.0b5",
"SHIPPING_PRODUCT": "fennec",
"TESTRAIL_PROJECT_ID": 59, # Fenix Browser
"TESTRAIL_PRODUCT_TYPE": "Firefox"
}

send_success_notification(success_values, 'channel_id', taskcluster_options)

values = {
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
"error_message": error_message,
}

send_error_notification(values, 'channel_id', taskcluster_options)
"""

import json
import os
import time
import traceback
from string import Template

import taskcluster

SLACK_SUCCESS_MESSAGE_TEMPLATE = Template(
"""
[
{
"type": "header",
"text": {
"type": "plain_text",
"text": "New Release: :firefox: $SHIPPING_PRODUCT-v$RELEASE_VERSION :star:"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Testrail Release*: $TESTRAIL_PRODUCT_TYPE $RELEASE_TYPE $RELEASE_VERSION <https://testrail.stage.mozaws.net/index.php?/projects/overview/$TESTRAIL_PROJECT_ID%7CMilestone> has been created:testrail:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*UI Automated Tests*:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": " :white_check_mark: Automated smoke test - Google Pixel 3(Android 11)"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":white_check_mark: Automated smoke test - Google Pixel 2(Android 9)"
}
},
{
"type": "divider"
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": ":testops-notify: created by <https://mozilla-hub.atlassian.net/wiki/spaces/MTE/overview%7CMobile Test Engineering>"
}
]
}
]
"""
)

SLACK_ERROR_MESSAGE_TEMPLATE = Template(
"""
[
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Failed to call TestRail API at $timestamp with error: $error_message"
}
}
]
"""
)


def send_slack_notification(template, values, channel_id, options):
"""
Sends a Slack notification based on the provided template and values.

:param template: Template object for the Slack message.
:param values: Dictionary containing values to substitute in the template.
:param channel_id: Slack channel ID to send the message to.
:param options: Taskcluster options for the notification service.
"""
slack_message = json.loads(template.safe_substitute(**values))
# workaround for https://github.com/taskcluster/taskcluster/issues/6801
duplicate_message_workaround = str(int(time.time()))
payload = {
"channelId": channel_id,
"text": duplicate_message_workaround,
"blocks": slack_message,
}

try:
response = taskcluster.Notify(options).slack(payload)
print("Response from API:", response)
except Exception as e:
print(f"Error sending Slack message: {e}")
traceback.print_exc()

if hasattr(e, "response"):
print("Response content:", e.response.text)


def get_taskcluster_options():
"""
Retrieves the Taskcluster setup options according to the current environment.

:return: A dictionary of Taskcluster options.
"""
options = taskcluster.optionsFromEnvironment()
proxy_url = os.environ.get("TASKCLUSTER_PROXY_URL")

if proxy_url is not None:
# Always use proxy url when available
options["rootUrl"] = proxy_url

if "rootUrl" not in options:
# Always have a value in root url
options["rootUrl"] = "https://community-tc.services.mozilla.com"

return options


def send_error_notification(error_message, channel_id, options):
values = {
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
"error_message": error_message,
}
send_slack_notification(SLACK_ERROR_MESSAGE_TEMPLATE, values, channel_id, options)


def send_success_notification(success_values, channel_id, options):
send_slack_notification(
SLACK_SUCCESS_MESSAGE_TEMPLATE, success_values, channel_id, options
)