diff --git a/.github/workflows/developer_onboarding_notification.yml b/.github/workflows/developer_onboarding_notification.yml new file mode 100644 index 000000000..0ed44fca4 --- /dev/null +++ b/.github/workflows/developer_onboarding_notification.yml @@ -0,0 +1,116 @@ +name: Celebrating Contributions + +on: + pull_request_target: + types: [closed] + +permissions: + pull-requests: write + +jobs: + comment_on_merged_pull_request: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set Environment Variables + env: + AUTHOR: ${{ github.event.pull_request.user.login }} + REPO: ${{ github.event.repository.name }} + OWNER: ${{ github.event.repository.owner.login }} + run: | + echo "AUTHOR=${AUTHOR}" >> $GITHUB_ENV + echo "REPO=${REPO}" >> $GITHUB_ENV + echo "OWNER=${OWNER}" >> $GITHUB_ENV + + - name: Count Merged Pull Requests + id: count_merged_pull_requests + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + const author = process.env.AUTHOR; + const repo = process.env.REPO; + const owner = process.env.OWNER; + const { data } = await github.rest.search.issuesAndPullRequests({ + q: `repo:${owner}/${repo} type:pr state:closed author:${author}` + }); + const prCount = data.items.filter(pr => pr.pull_request.merged_at).length; + core.exportVariable('PR_COUNT', prCount); + } catch (error) { + core.setFailed(`Error counting merged pull requests: ${error.message}`); + } + + - name: Comment on the Merged Pull Request + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + const prCount = parseInt(process.env.PR_COUNT); + const author = process.env.AUTHOR; + const mention = 'talboren'; + const prNumber = context.payload.pull_request.number; + const repo = process.env.REPO; + + function getRandomEmoji() { + const emojis = ['🎉', '🚀', '💪', '🌟', '🏆', '🎊', '🔥', '👏', '🌈', '🚂']; + return emojis[Math.floor(Math.random() * emojis.length)]; + } + + function getMessage(count) { + const emoji = getRandomEmoji(); + switch(count) { + case 1: + return `${emoji} **Fantastic work @${author}!** Your very first PR to ${repo} has been merged! 🎉🥳\n\n` + + `You've just taken your first step into open-source, and we couldn't be happier to have you onboard. 🙌\n` + + `If you're feeling adventurous, why not dive into another issue and keep contributing? The community would love to see more from you! 🚀\n\n` + + `For any support, feel free to reach out to the developer onboarding lead: @${mention}. Happy coding! 👩‍💻👨‍💻`; + case 2: + return `${emoji} **Well done @${author}!** Two PRs merged already! 🎉🥳\n\n` + + `With your second PR, you're on a roll, and your contributions are already making a difference. 🌟\n` + + `Looking forward to seeing even more contributions from you. The developer onboarding lead: @${mention} is here if you need any help! Keep up the great work! 🚀`; + case 3: + return `${emoji} **You're on fire, @${author}!** Three PRs merged and counting! 🔥🎉\n\n` + + `Your consistent contributions are truly impressive. You're becoming a valued member of our community! 💖\n` + + `Have you considered taking on some more challenging issues? We'd love to see what you can do! 💪\n\n` + + `Remember, @${mention} is always here to support you. Keep blazing that trail! 🚀`; + case 5: + return `${emoji} **High five, @${author}!** You've hit the incredible milestone of 5 merged PRs! 🖐️✨\n\n` + + `Your dedication to ${repo} is outstanding. You're not just contributing code; you're shaping the future of this project! 🌠\n` + + `We'd love to hear your thoughts on the project. Any ideas for new features or improvements? 🤔\n\n` + + `@${mention} and the whole team applaud your efforts. You're a superstar! 🌟`; + case 10: + return `${emoji} **Double digits, @${author}!** 10 merged PRs is a massive achievement! 🏆🎊\n\n` + + `Your impact on ${repo} is undeniable. You've become a pillar of our community! 🏛️\n` + + `We'd be thrilled to have you take on a mentorship role for newer contributors. Interested? 🧑‍🏫\n\n` + + `@${mention} and everyone here are in awe of your contributions. You're an open source hero! 🦸‍♀️🦸‍♂️`; + default: + if (count > 10) { + return `${emoji} **Incredible, @${author}!** You've merged your ${count}th PR! 🎯🎊\n\n` + + `Your ongoing commitment to ${repo} is truly remarkable. You're a driving force in our community! 🚀\n` + + `Your contributions are helping to shape the future of this project. What exciting features or improvements do you envision next? 🔮\n\n` + + `@${mention} and the entire team are grateful for your dedication. You're an inspiration to us all! 💫`; + } else { + return `${emoji} **Great job, @${author}!** You've merged your ${count}th PR! 🎊\n\n` + + `Your contributions to ${repo} are making a real difference. Keep up the fantastic work! 💪\n` + + `Remember, every PR counts and helps improve the project. What will you tackle next? 🤔\n\n` + + `@${mention} is here if you need any guidance. Onward and upward! 🚀`; + } + } + } + + const message = getMessage(prCount); + + await github.rest.issues.createComment({ + owner: process.env.OWNER, + repo: process.env.REPO, + issue_number: prNumber, + body: message + }); + } catch (error) { + core.setFailed(`Error creating comment: ${error.message}`); + } \ No newline at end of file diff --git a/examples/workflows/consts_and_vars.yml b/examples/workflows/consts_and_vars.yml new file mode 100644 index 000000000..29501e3c2 --- /dev/null +++ b/examples/workflows/consts_and_vars.yml @@ -0,0 +1,147 @@ +workflow: + id: sa_pipeline_status_alert + description: gpu_test + triggers: + - type: alert + filters: + - key: source + value: "openobserve" + name: gpu_test + + # consts block for email_template and slack_message + consts: + email_template: | + Hi,
+ This {{ vars.alert_tier }} is triggered because the pipelines for {{ alert.host }} are down for more than keep.get_firing_time('{{ alert }}', 'minutes') minutes.
+ Please visit monitoring.keeohq.dev for more!
+ Regards,
+ KeepHQ dev Monitoring
+ + slack_message: | + {{ vars.alert_tier }} Alert: SA Pipelines are down + + Hi, + This {{ vars.alert_tier }} alert is triggered because the pipelines for {{ alert.host }} are down for more than keep.get_firing_time('{{ alert }}', 'minutes') minutes. + Please visit monitoring.keeohq.dev for more! + + actions: + # Sendgrid Tier 0 Alert + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 0 and keep.get_firing_time('{{ alert }}', 'minutes') < 10" + name: Sendgrid_Tier_0_alert + vars: + alert_tier: "Alert 0" + provider: + config: "{{ providers.Sendgrid }}" + type: sendgrid + with: + to: + - "shahar@keephq.dev" + subject: '"Tier 0 Alert: SA Pipelines are down"' + html: "{{ consts.email_template }}" + + # Sendgrid Tier 1 Alert + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 10 and keep.get_firing_time('{{ alert }}', 'minutes') < 15" + name: Sendgrid_Tier_1_alert + vars: + alert_tier: "Alert 1" + provider: + config: "{{ providers.Sendgrid }}" + type: sendgrid + with: + to: + - "shahar@keephq.dev" + subject: '"Tier 1 Alert: SA Pipelines are down"' + html: "{{ consts.email_template }}" + + # Sendgrid Tier 2 Alert + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 60 and keep.get_firing_time('{{ alert }}', 'minutes') < 70" + name: Sendgrid_Tier_2_alert + vars: + alert_tier: "Alert 2" + provider: + config: "{{ providers.Sendgrid }}" + type: sendgrid + with: + to: + - "shahar@keephq.dev" + subject: '"Tier 2 Alert: SA Pipelines are down"' + html: "{{ consts.email_template }}" + + # Sendgrid Tier 3 Alert + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 120 and keep.get_firing_time('{{ alert }}', 'minutes') < 130" + name: Sendgrid_Tier_3_alert + vars: + alert_tier: "Alert 3" + provider: + config: "{{ providers.Sendgrid }}" + type: sendgrid + with: + to: + - "shahar@keephq.dev" + subject: '"Tier 3 Alert: SA Pipelines are down"' + html: "{{ consts.email_template }}" + + # Sendgrid Tier 4 Alert + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 1440 and keep.get_firing_time('{{ alert }}', 'minutes') < 1450" + name: Sendgrid_Tier_4_alert + vars: + alert_tier: "Alert 4" + provider: + config: "{{ providers.Sendgrid }}" + type: sendgrid + with: + to: + - "shahar@keephq.dev" + subject: '"Tier 4 Alert: SA Pipelines are down"' + html: "{{ consts.email_template }}" + + # Slack Alerts + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 0 and keep.get_firing_time('{{ alert }}', 'minutes') < 10" + name: Slack_Tier_0_alert + vars: + alert_tier: "Alert 0" + provider: + config: "{{ providers.dev_slack }}" + type: slack + with: + message: "{{ consts.slack_message }}" + + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 10 and keep.get_firing_time('{{ alert }}', 'minutes') < 15" + name: Slack_Tier_1_alert + vars: + alert_tier: "Alert 1" + provider: + config: "{{ providers.dev_slack }}" + type: slack + with: + message: "{{ consts.slack_message }}" + + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 60 and keep.get_firing_time('{{ alert }}', 'minutes') < 70" + name: Slack_Tier_2_alert + vars: + alert_tier: "Alert 2" + provider: + config: "{{ providers.dev_slack }}" + type: slack + with: + message: "{{ consts.slack_message }}" + + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 120 and keep.get_firing_time('{{ alert }}', 'minutes') < 130" + name: Slack_Tier_3_alert + vars: + alert_tier: "Alert 3" + provider: + config: "{{ providers.dev_slack }}" + type: slack + with: + message: "{{ consts.slack_message }}" + + - if: "keep.get_firing_time('{{ alert }}', 'minutes') >= 1440 and keep.get_firing_time('{{ alert }}', 'minutes') < 1450" + name: Slack_Tier_4_alert + vars: + alert_tier: "Alert 4" + provider: + config: "{{ providers.dev_slack }}" + type: slack + with: + message: "{{ consts.slack_message }}" diff --git a/keep-ui/app/globals.css b/keep-ui/app/globals.css index 1b814cf17..a05e00ebf 100644 --- a/keep-ui/app/globals.css +++ b/keep-ui/app/globals.css @@ -45,3 +45,7 @@ } } +.sliding-panel-container.active { + /* original value is ridiculous 15.000, overflowing toasts*/ + @apply z-[1000] !important; +} diff --git a/keep-ui/app/incidents/[id]/incident-info.tsx b/keep-ui/app/incidents/[id]/incident-info.tsx index 2558b0057..364965010 100644 --- a/keep-ui/app/incidents/[id]/incident-info.tsx +++ b/keep-ui/app/incidents/[id]/incident-info.tsx @@ -20,6 +20,9 @@ import { IoChevronDown } from "react-icons/io5"; import IncidentChangeStatusModal from "@/app/incidents/incident-change-status-modal"; import ChangeSameIncidentInThePast from "@/app/incidents/incident-change-same-in-the-past"; import {STATUS_ICONS} from "@/app/incidents/statuses"; +import remarkRehype from "remark-rehype"; +import rehypeRaw from "rehype-raw"; +import Markdown from "react-markdown"; interface Props { incident: IncidentDto; @@ -45,6 +48,14 @@ function Summary({ collapsable?: boolean; className?: string; }) { + + const formatedSummary = + {summary} + + if (collapsable) { return ( @@ -60,7 +71,7 @@ function Summary({ - {summary} + {formatedSummary} ); @@ -70,7 +81,7 @@ function Summary({

{title}

{/*TODO: suggest generate summary if it's empty*/} - {summary ?

{summary}

:

No summary yet

} + {summary ?

{formatedSummary}

:

No summary yet

}
); } diff --git a/keep-ui/app/incidents/create-or-update-incident.tsx b/keep-ui/app/incidents/create-or-update-incident.tsx index 149222706..2ae75422b 100644 --- a/keep-ui/app/incidents/create-or-update-incident.tsx +++ b/keep-ui/app/incidents/create-or-update-incident.tsx @@ -18,6 +18,9 @@ import { IncidentDto } from "./models"; import { useIncidents } from "utils/hooks/useIncidents"; import { Session } from "next-auth"; import { useUsers } from "utils/hooks/useUsers"; +const ReactQuill = + typeof window === "object" ? require("react-quill") : () => false; +import "react-quill/dist/quill.snow.css"; interface Props { incidentToEdit: IncidentDto | null; @@ -157,6 +160,32 @@ export default function CreateOrUpdateIncident({ return !!incidentName; }; + const formats = [ + "header", + "bold", + "italic", + "underline", + "list", + "bullet", + "link", + "align", + "blockquote", + "code-block", + "color", + ]; + + const modules = { + toolbar: [ + [{ header: "1" }, { header: "2" }], + [{ list: "ordered" }, { list: "bullet" }], + ["bold", "italic", "underline"], + ["link"], + [{ align: [] }], + ["blockquote", "code-block"], // Add quote and code block options to the toolbar + [{ color: [] }], // Add color option to the toolbar + ], + }; + return (
Incident Metadata @@ -173,10 +202,14 @@ export default function CreateOrUpdateIncident({
Summary -