Compare commits

...

8 Commits

Author SHA1 Message Date
cc640700a4 fix: 🐛 Make Commit Author envs optional
All checks were successful
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
In some pipelines the commit author is not available (i.e. cron). Use "Woodpecker" and Woodpecker's Favicon as a placeholder if the author is missing
2025-04-18 11:42:21 +02:00
a84fc769ac Update&fix notifier for new woodpecker version
All checks were successful
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
2025-03-06 09:01:08 +01:00
2b00dcc305 ci: 💚 use jq -r to strip quotes in output
All checks were successful
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
2024-10-31 11:05:24 +01:00
cc526eb592 me be dum
Some checks failed
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline failed
2024-10-31 10:56:57 +01:00
b9616bb19e i guess we rawdogging digests over here
Some checks failed
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline failed
2024-10-31 10:49:23 +01:00
63e72559be i guess we rawdogging digests over here
Some checks failed
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline failed
2024-10-31 10:44:44 +01:00
0b543c5b70 ci: 🚧 pre-log in and pull image with docker for scan?
Some checks failed
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline failed
2024-10-31 10:17:46 +01:00
4de3431e50 Make image scan with debug
Some checks failed
ci/woodpecker/push/scans Pipeline was successful
ci/woodpecker/push/build Pipeline failed
2024-10-31 10:06:56 +01:00
2 changed files with 63 additions and 46 deletions

View File

@@ -56,6 +56,21 @@ steps:
when: when:
- event: push - event: push
branch: main branch: main
- name: gather-digests
image: quay.io/skopeo/stable:latest
environment:
DOCKER_USER:
from_secret: registry_username
DOCKER_PASS:
from_secret: registry_password
when:
- event: push
branch: main
commands:
- dnf install -y jq
- skopeo login dev.shielddagger.com --username $DOCKER_USER --password $DOCKER_PASS
- skopeo inspect --raw docker://dev.shielddagger.com/opensource/discord-notifier:latest | jq -r .'manifests[] | select(.platform.architecture=="arm64").digest' > digest-arm64
- skopeo inspect --raw docker://dev.shielddagger.com/opensource/discord-notifier:latest | jq -r .'manifests[] | select(.platform.architecture=="amd64").digest' > digest-amd64
- name: image-scan - name: image-scan
image: aquasec/trivy image: aquasec/trivy
environment: environment:
@@ -67,7 +82,8 @@ steps:
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db
TRIVY_CHECKS_BUNDLE_REPOSITORY: public.ecr.aws/aquasecurity/trivy-checks TRIVY_CHECKS_BUNDLE_REPOSITORY: public.ecr.aws/aquasecurity/trivy-checks
commands: commands:
- trivy image dev.shielddagger.com/opensource/discord-notifier:latest --exit-code 1 --username $TRIVY_USER --severity HIGH,CRITICAL - export ARM64_DIGEST=$(cat digest-arm64)
- trivy image --platform linux/arm64 --debug dev.shielddagger.com/opensource/discord-notifier@$ARM64_DIGEST --exit-code 1 --username $TRIVY_USER --severity HIGH,CRITICAL
when: when:
- event: push - event: push
branch: main branch: main

View File

@@ -10,6 +10,13 @@ from urllib.parse import urljoin, urlparse
from requests import Session from requests import Session
from requests.models import Response from requests.models import Response
logfile_webhook = DiscordWebhook(environ["PLUGIN_WEBHOOK_URL"], rate_limit_retry=True)
logfile_webhook.username = "Woodpecker CI"
logfile_webhook.avatar_url = "https://ci.shielddagger.com/favicons/favicon-dark-error.png"
webhook = DiscordWebhook(environ["PLUGIN_WEBHOOK_URL"], rate_limit_retry=True)
webhook.username = "Woodpecker CI"
class APISession(Session): class APISession(Session):
def __init__(self, base_url) -> None: def __init__(self, base_url) -> None:
@@ -19,13 +26,44 @@ class APISession(Session):
def request(self, method: str | bytes, url: str | bytes, *args, **kwargs) -> Response: def request(self, method: str | bytes, url: str | bytes, *args, **kwargs) -> Response:
url = urljoin(self.base_url, url) url = urljoin(self.base_url, url)
return super().request(method, url, *args, **kwargs) return super().request(method, url, *args, **kwargs)
try:
ci_client = APISession(environ["PLUGIN_WOODPECKER_URL"].rstrip("/"))
ci_client.headers.setdefault("Authorization", f"Bearer {environ["PLUGIN_WOODPECKER_TOKEN"]}")
except KeyError:
webhook.add_embed(DiscordEmbed(
"API Error",
"API access has not been configured.\n"\
"As a result, Discord Notifier is unable to retrieve job information like logs or status.\n"\
"Please use the `woodpecker_url` and `woodpecker_token` settings to allow API access.",
color="ED4345",
timestamp=datetime.now(UTC),
footer={
"text": "Discord Notifier",
"icon_url": "https://dev.shielddagger.com/repo-avatars/273e88fa2afde290121dc7b5987dc366b88325f147bf1e5766bca26296bbc1f9"
}
))
webhook.execute()
exit(1)
logfile_webhook = None pipeline_url = urlparse(environ["CI_PIPELINE_URL"]).path.lstrip("/").split("/")
webhook = DiscordWebhook(environ["PLUGIN_WEBHOOK_URL"], rate_limit_retry=True) repo_id = pipeline_url[1]
pipeline_number = pipeline_url[3]
success = environ["CI_PIPELINE_STATUS"] != "failure" pipeline_info = ci_client.get(f"/api/repos/{repo_id}/pipelines/{pipeline_number}").json()
success = None
for workflow in pipeline_info["workflows"]:
if workflow["name"] != environ["CI_WORKFLOW_NAME"]:
continue
for step in workflow["children"]:
if step["state"] != "failure":
continue
loginfo = ci_client.get(f"/api/repos/{repo_id}/logs/{pipeline_number}/{step['id']}").json()
logdata = b""
for logline in loginfo:
logdata += b64decode(logline["data"]) + b"\n"
logfile_webhook.add_file(logdata, f"{step['name']}.ansi")
success = all(step["state"] != "failure" for step in workflow["children"])
webhook.username = "Woodpecker CI"
webhook.avatar_url = "https://ci.shielddagger.com/favicons/favicon-dark-success.png" if success else \ webhook.avatar_url = "https://ci.shielddagger.com/favicons/favicon-dark-success.png" if success else \
"https://ci.shielddagger.com/favicons/favicon-dark-error.png" "https://ci.shielddagger.com/favicons/favicon-dark-error.png"
@@ -39,8 +77,8 @@ webhook.add_embed(DiscordEmbed(
"url": environ["CI_REPO_URL"] "url": environ["CI_REPO_URL"]
}, },
footer={ footer={
"text": environ["CI_COMMIT_AUTHOR"], "text": environ.get("CI_COMMIT_AUTHOR", "Woodpecker"),
"icon_url": environ["CI_COMMIT_AUTHOR_AVATAR"] "icon_url": environ.get("CI_COMMIT_AUTHOR_AVATAR", "https://ci.shielddagger.com/favicons/favicon-dark-default.png")
}, },
thumbnail={ thumbnail={
"url": getenv("PLUGIN_ICON_URL"), "url": getenv("PLUGIN_ICON_URL"),
@@ -65,47 +103,10 @@ webhook.add_embed(DiscordEmbed(
}] }]
)) ))
try:
if not success:
logfile_webhook = DiscordWebhook(environ["PLUGIN_WEBHOOK_URL"], rate_limit_retry=True)
logfile_webhook.username = "Woodpecker CI"
logfile_webhook.avatar_url = "https://ci.shielddagger.com/favicons/favicon-dark-error.png"
with APISession(environ["PLUGIN_WOODPECKER_URL"].rstrip("/")) as client:
client.headers.setdefault("Authorization", f"Bearer {environ["PLUGIN_WOODPECKER_TOKEN"]}")
pipeline_url = urlparse(environ["CI_PIPELINE_URL"]).path.lstrip("/").split("/")
repo_id = pipeline_url[1]
pipeline_number = pipeline_url[3]
pipeline_info = client.get(f"/api/repos/{repo_id}/pipelines/{pipeline_number}").json()
for workflow in pipeline_info["workflows"]:
if workflow["name"] != environ["CI_WORKFLOW_NAME"]:
continue
for step in workflow["children"]:
if step["state"] != "failure":
continue
loginfo = client.get(f"/api/repos/{repo_id}/logs/{pipeline_number}/{step['id']}").json()
logdata = b""
for logline in loginfo:
logdata += b64decode(logline["data"]) + b"\n"
logfile_webhook.add_file(logdata, f"{step['name']}.ansi")
except KeyError:
webhook.add_embed(DiscordEmbed(
"API Error",
"API access has not been configured.\n"\
"As a result, Discord Notifier is unable to retrieve failed job logs to attach here.\n"\
"Please use the `woodpecker_url` and `woodpecker_token` settings to allow API access.",
color="ED4345",
timestamp=datetime.now(UTC),
footer={
"text": "Discord Notifier",
"icon_url": "https://dev.shielddagger.com/repo-avatars/273e88fa2afde290121dc7b5987dc366b88325f147bf1e5766bca26296bbc1f9"
}
))
pprint(webhook.json) pprint(webhook.json)
webhook.execute() webhook.execute()
if logfile_webhook is not None: if not success:
pprint(logfile_webhook.json) pprint(logfile_webhook.json)
logfile_webhook.execute() logfile_webhook.execute()