Allow notification plugins to notify about the pipeline status
Opened this issue · 18 comments
Clear and concise description of the problem
The env var CI_PIPELINE_STATUS
war broken already and has always reported success
but was now removed completely in #3846
Right now, I don't see any way to use a notification plugin in pipelines to send build status notifications to an external system.
Suggested solution
Add back CI_PIPELINE_STATUS
and populate the correct status. We have the correct pipeline status in the UI/API already, why can't we just populate it to the env?
Alternative
No response
Additional context
No response
Validations
CI_PIPELINE_STATUS and populate the correct status
Will always be running
:)
Well coming from Drone I can at least tell you there was a working and stable implementation.
there was a working and stable implementation
Sure. I didn't say that it is impossible. Do you know how it's implemented there?
Could you show an example pipeline? Does watched step have to define failure: ignore
?
If we are using failure: ignore
on watched step and notification step within the same pipeline, then one of implementations could be var like CI_STEPS_STATUSES
with value like clone:success,test:success,build:fail
. Or separate variables like CI_STEP_CLONE_STATUS:success
and so on.
Another solution could be webhooks to external notification service.
We have the correct pipeline status in the UI/API already, why can't we just populate it to the env?
Yet another one: use special step type likeservice
, but notification
. It would always run after pipeline finishes and yes can contain correct CI_PIPELINE_STATUS
.
Sure. I didn't say that it is impossible. Do you know how it's implemented there?
Drone uses some kind of hooks https://github.com/harness/harness/blob/drone/operator/runner/runner.go#L380-L402 which looks kinda similar to what we had in place already. That's why I'm wondering why it was broken in Woodpecker...
Could you show an example pipeline? Does watched step have to define failure: ignore?
https://github.com/thegeeklab/wp-matrix/blob/main/.woodpecker/notify.yml
Yet another one: use special step type likeservice, but notification. It would always run after pipeline finishes and yes can contain correct CI_PIPELINE_STATUS.
Sure could be done this way also.
Thank you for an example. Wasn't aware of runs_on
. It's like my special step type
:)
Agree that it was/is a bug and should be fixed. But in the example it is still the same pipeline, pipeline status is running
. Maybe there could be var like CI_WORKFLOW_STATUSES
.
Drone has status trigger. Seems it was when.status in previous versions.
Besides runs_on
there is when.status in Woodpecker. Assuming it works as described in the docs, there should be some env var in the step, carrying the status of "entity", used in when.status
.
steps:
- name: slack
image: plugins/slack
settings:
channel: dev
when:
- status: [ success, failure ]
steps:
- name: notify
image: debian:stable-slim
commands:
- echo notifying
runs_on: [ success, failure ]
Related to drone: DRONE_BUILD_STATUS, DRONE_STAGE_STATUS, DRONE_BUILD_FINISHED, DRONE_STAGE_FINISHED.
The agent is pulling the next workflow to execute from the queue but I cant see any way to access the parent pipeline information from the agent. Do I miss something? Is there any existing way to look up the pipeline with the given information from rpc.Workflow
on the agent?
You can probably look it up via REST and even make custom GRPC method, but why. It's the server responsibility to set (almost) all vars. And this map sends to the agent.
This map is only set once during the pipeline creation and can only contain static values that dont change during workflow executions. For the pipeline state it must be looked up before a workflow is pulled from the queue and executed.
Notifications have to be executed after all ... what actually (steps in workflow or workflows)? Do you want notification per workflow or per pipeline?
Per pipeline.I think you can now define the separate notifications workflow asdepends_on
others in a way it executes the last (after workflows you want notifications about). So at the time the notifications workflow is ready to execute, the Server will know the statuses of all other executed workflows. The server sets up envCI_WORKFLOW_STATUSES
(or separate ones) and sends the notifications workflow into queue. Agent picks it up and all works.- It actually works for both workflows statuses and pipeline. So you have statuses of each workflow. And if all workflows are success, then the pipeline is also success -> you can set
PIPELINE_STATUS
on the server a bit in advance.
Anyway, how the example works now?
steps:
- name: slack
image: plugins/slack
settings:
channel: dev
when:
- status: [ success, failure ]
Server should defer this last step, wait for other steps (?), get status of workflow (?) and then depending on condition run the step. Right?
Maybe I miss something, but I don't see how your approach should work:
- Pipeline is triggered by event
- Pipeline config will be parsed, and all workflows will be compiled and added to the queue. At this point all static env vars from the location you have linked are already added to the workflow metadata before they are added to the queue.
- Workflows are executed, one or more failed but the notification workflow which is already in the queue at this point doesnt know about the changed pipeline state (how should it?)
all workflows will be compiled and added to the queue
the notification workflow which is already in the queue
All except notifications. Compile ... maybe, but not put in queue. Before scheduling, statuses should be set. That was the point in my approach. Agree, that now it might not work, but it could be some mark in syntax to define such workflows.
And still, I wonder
- Does the examples work at all?
- How do they work then? Because before we (server?) run a step with
when.status:failure
we needfailure
of some "entity".
Edit
What we can do now is
- Define notification step or workflow-with-depend-on.
- Make notifications plugin to call the Server via REST for whatever statuses (step, workflow) we want. The whole pipeline status can be interpolated a little bit in advance as I mentioned before.
the current pipeline status is just technically undefined till it has finished.
and CI_PREV_PIPELINE_STATUS
is still here ... so i dont get what the problem is ...
also taling abaut notification plugin you might wana have a look into CI_PREV_STEP_STATUS
Goal: At the end of a pipeline I want to have a step that sends the current pipeline (not workflow, not step) status (success or failure) to an external system. Is this possible right now?
and CI_PREV_PIPELINE_STATUS is still here ... so i dont get what the problem is ...
How does the previous pipeline status helps here? Some pipelines are running very long. Checking the web UI or forge PR status frequently is annoying. That's why I want a way to send a notification with the pipeline status as the last step of a pipeline to an external system e.g. mail, chat, push gateway etc. Using Drone CI this was easily possible, see my comments above.
the current pipeline status is just technically undefined till it has finished.
Well, no. The pipeline status can be success or failure. It is set to success by default and changed to failure after the first step in a pipeline has failed (unless the step is configured to ignore failures). Again, as a former Drone user I can just tell you that this feature was easy to use and stable since years without needing a too complicated mechanism see https://docs.drone.io/pipeline/environment/reference/drone-build-status/
From the Drone docs:
Please note this is point in time snapshot. This value may not accurately reflect the overall build status when multiple pipelines are running in parallel.
While that's obvious, we have already a mechanism in Woodpecker as well to ensure that the notification step is the last step executed in a pipeline, but it also allows users to get the point in time pipeline status as well if required.
Is this possible right now?
It should have been possible with
# build.yaml
skip_clone: true
steps:
build:
image: alpine
commands:
- echo 'Building the app'
- exit 1 # 0 - success, 1 - fail
# notifications.yaml
skip_clone: true
depends_on: [build]
runs_on: [success, failure]
steps:
fail-notification:
when:
- status: [failure]
image: alpine
commands:
- echo 'Build failed'
success-notification:
when:
- status: [success]
image: alpine
commands:
- echo 'Build succeed'
Tested on 2.7.1
and next
. Looks like a bug to me. Should I file it as separate bug-issue?
This is a separate bug IMO. But to make it a bit more clear, even if this bug doesn't exist, this way is more a hack and not a proper solution for notifications.
When did CI_PIPELINE_STATUS
stop working? It's been working reliably for me since before 2.0 and still is on 2.7.3 (I use it as part of a notifier script, running both on failure and success).
See the linked PR in the issue description.
I first found the PR thanks to the release notes of the 3.0 release candidate, and then this issue: I didn't see any bisection/mention of when the variable was broken.