mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-05-11 18:06:34 +00:00
Fix pipeline source information (#5011)
This commit is contained in:
parent
c392250384
commit
23a7b2f17d
cmd/agent/core
docs
docs
src/pages
pipeline
server
@ -247,12 +247,10 @@ func run(ctx context.Context, c *cli.Command, backends []types.Backend) error {
|
||||
|
||||
// set default labels ...
|
||||
labels := make(map[string]string)
|
||||
for label := range pipeline.ManagedLabels {
|
||||
labels[label] = "*"
|
||||
}
|
||||
labels[pipeline.LabelHostname] = hostname
|
||||
labels[pipeline.LabelPlatform] = engInfo.Platform
|
||||
labels[pipeline.LabelBackend] = backendEngine.Name()
|
||||
labels[pipeline.LabelFilterHostname] = hostname
|
||||
labels[pipeline.LabelFilterPlatform] = engInfo.Platform
|
||||
labels[pipeline.LabelFilterBackend] = backendEngine.Name()
|
||||
labels[pipeline.LabelFilterRepo] = "*" // allow all repos by default
|
||||
// ... and let it overwrite by custom ones
|
||||
maps.Copy(labels, customLabels)
|
||||
|
||||
|
@ -594,34 +594,24 @@ For more details check the [matrix build docs](./30-matrix-workflows.md).
|
||||
|
||||
## `labels`
|
||||
|
||||
Use labels to select the agent that executes your workflow. An agent will execute a workflow only if **all** its assigned labels match the workflow's labels. For Kubernetes agents, these labels propagate to any related resources created during pipeline execution, including pods and secrets.
|
||||
To configure additional agent labels, see the [agent configuration options](../30-administration/10-configuration/30-agent.md#agent_labels). Agents have pre-configured filters for the following labels:
|
||||
You can define labels for your workflow in order to select an agent to execute the workflow. An agent takes up a workflow and executes it if **every** label assigned to it matches the label of the agent.
|
||||
|
||||
| Label | Description | Woodpecker managed |
|
||||
|------------------------------------|--------------------------------------------------------------------|--------------------|
|
||||
| `woodpecker-ci.org/forge-id` | Internal Forge identifier | 🤖 yes |
|
||||
| `woodpecker-ci.org/repo-forge-id` | Repository identifier from the Forge | 🤖 yes |
|
||||
| `woodpecker-ci.org/repo-id` | Internal repository identifier | 🤖 yes |
|
||||
| `woodpecker-ci.org/repo-name` | Repository display name (excluding project/organization) | 🤖 yes |
|
||||
| `woodpecker-ci.org/repo-full-name` | Repository display name (including project/organization) | 🤖 yes |
|
||||
| `woodpecker-ci.org/branch` | Git branch name | 🤖 yes |
|
||||
| `woodpecker-ci.org/org-id` | Internal organization/project identifier | 🤖 yes |
|
||||
| `repo` | (deprecated) Combined repository and project name (`org/git_repo`) | 🤖 yes |
|
||||
| `platform` | (deprecated) Agent OS and CPU architecture (e.g., `linux/amd64`) | 🧑💻 no |
|
||||
| `hostname` | Agent name | 🧑💻 no |
|
||||
| `backend` | Agent's backend technology (kubernetes, docker, local) | 🧑💻 no |
|
||||
| `org-id` | Internal organization/project identifier | 🤖 yes |
|
||||
To specify additional agent labels, check the [Agent configuration options] (../30-administration/10-configuration/30-agent.md#agent_labels). The agents have at least four default labels: `platform=agent-os/agent-arch`, `hostname=my-agent`, `backend=docker` (type of agent backend) and `repo=*`. Agents can use an `*` as a placeholder for a label. For example, `repo=*` matches any repo.
|
||||
|
||||
You can add more labels as key-value pairs under the `labels` field in your pipeline. Labels marked as Woodpecker managed can not be set as part of the pipeline definition. Labels with empty values are ignored.
|
||||
Workflow labels with an empty value are ignored.
|
||||
By default, each workflow has at least the label `repo=your-user/your-repo-name`. If you have set the [platform attribute](#platform) for your workflow, it will also have a label such as `platform=your-os/your-arch`.
|
||||
|
||||
Specifying the [platform attribute](#platform) for your workflow automatically adds a corresponding `woodpecker-ci.org/platform` label, such as `woodpecker-ci.org/platform=your-os/your-arch`.
|
||||
:::warning
|
||||
Labels with the `woodpecker-ci.org` prefix are managed by Woodpecker and can not be set as part of the pipeline definition.
|
||||
:::
|
||||
|
||||
You can add additional labels as a key value map:
|
||||
|
||||
```diff
|
||||
+labels:
|
||||
+ location: europe # Only agents with `location=europe` or `location=*` will execute this workflow.
|
||||
+ location: europe # only agents with `location=europe` or `location=*` will be used
|
||||
+ weather: sun
|
||||
+ hostname: "" # Ignored because the value is empty.
|
||||
+ woodpecker-ci.org/forge-id: 1 # Ignored because it sets a managed label.
|
||||
+ hostname: "" # this label will be ignored as it is empty
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
|
@ -6,6 +6,20 @@ toc_max_heading_level: 2
|
||||
|
||||
The Kubernetes backend executes steps inside standalone Pods. A temporary PVC is created for the lifetime of the pipeline to transfer files between steps.
|
||||
|
||||
## Metadata labels
|
||||
|
||||
Woodpecker adds some labels to the pods to provide additional context to the workflow. These labels can be used for various purposes, e.g. for simple debugging or as selectors for network policies.
|
||||
|
||||
The following metadata labels are supported:
|
||||
|
||||
- `woodpecker-ci.org/forge-id`
|
||||
- `woodpecker-ci.org/repo-forge-id`
|
||||
- `woodpecker-ci.org/repo-id`
|
||||
- `woodpecker-ci.org/repo-name`
|
||||
- `woodpecker-ci.org/repo-full-name`
|
||||
- `woodpecker-ci.org/branch`
|
||||
- `woodpecker-ci.org/org-id`
|
||||
|
||||
## Private registries
|
||||
|
||||
In addition to [registries specified in the UI](../../../20-usage/41-registries.md), you may provide [registry credentials in Kubernetes Secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) to pull private container images defined in your pipeline YAML.
|
||||
|
@ -5,16 +5,6 @@ To enhance the usability of Woodpecker and meet evolving security standards, occ
|
||||
## `next`
|
||||
|
||||
- (Kubernetes) Deprecated `step` label on pod in favor of new namespaced label `woodpecker-ci.org/step`. The `step` label will be removed in a future update.
|
||||
- Deprecated several labels in favor of equivalents with the `woodpecker-ci.org/` prefix. The deprecated labels will be removed in a future update.
|
||||
The following labels are affected:
|
||||
|
||||
| Deprecated labels | New labels |
|
||||
| ----------------- | ---------------------------------- |
|
||||
| `repo` | `woodpecker-ci.org/repo-full-name` |
|
||||
| `platform` | `woodpecker-ci.org/platform` |
|
||||
| `hostname` | `woodpecker-ci.org/hostname` |
|
||||
| `backend` | `woodpecker-ci.org/backend` |
|
||||
| `org-id` | `woodpecker-ci.org/org-id` |
|
||||
|
||||
## 3.0.0
|
||||
|
||||
|
@ -29,18 +29,9 @@ const (
|
||||
LabelRepoFullName string = InternalLabelPrefix + "/repo-full-name"
|
||||
LabelBranch string = InternalLabelPrefix + "/branch"
|
||||
LabelOrgID string = InternalLabelPrefix + "/org-id"
|
||||
LabelPlatform string = "platform"
|
||||
LabelHostname string = "hostname"
|
||||
LabelBackend string = "backend"
|
||||
LabelFilterOrg string = "org-id"
|
||||
LabelFilterRepo string = "repo"
|
||||
LabelFilterPlatform string = "platform"
|
||||
LabelFilterHostname string = "hostname"
|
||||
LabelFilterBackend string = "backend"
|
||||
)
|
||||
|
||||
// ManagedLabels is a list of all labels added automatically to tasks by Woodpecker.
|
||||
var ManagedLabels = map[string]bool{
|
||||
LabelForgeRemoteID: true,
|
||||
LabelRepoForgeID: true,
|
||||
LabelRepoID: true,
|
||||
LabelRepoName: true,
|
||||
LabelRepoFullName: true,
|
||||
LabelBranch: true,
|
||||
LabelOrgID: true,
|
||||
}
|
||||
|
@ -15,6 +15,9 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
pipelineConsts "go.woodpecker-ci.org/woodpecker/v3/pipeline"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/rpc"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/model"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/queue"
|
||||
@ -22,6 +25,13 @@ import (
|
||||
|
||||
func createFilterFunc(agentFilter rpc.Filter) queue.FilterFn {
|
||||
return func(task *model.Task) (bool, int) {
|
||||
// ignore internal labels for filtering
|
||||
for k := range task.Labels {
|
||||
if strings.HasPrefix(k, pipelineConsts.InternalLabelPrefix) {
|
||||
delete(task.Labels, k)
|
||||
}
|
||||
}
|
||||
|
||||
score := 0
|
||||
for taskLabel, taskLabelValue := range task.Labels {
|
||||
// if a task label is empty it will be ignored
|
||||
|
@ -28,7 +28,6 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
grpcMetadata "google.golang.org/grpc/metadata"
|
||||
|
||||
pipelineConsts "go.woodpecker-ci.org/woodpecker/v3/pipeline"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/pipeline/rpc"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/forge"
|
||||
@ -52,44 +51,12 @@ type RPC struct {
|
||||
pipelineCount *prometheus.CounterVec
|
||||
}
|
||||
|
||||
// Replaces legacy filter labels with new ones.
|
||||
func migrateFilterLabels(filter rpc.Filter) rpc.Filter {
|
||||
if value, ok := filter.Labels["repo"]; ok {
|
||||
filter.Labels[pipelineConsts.LabelRepoFullName] = value
|
||||
delete(filter.Labels, "repo")
|
||||
}
|
||||
|
||||
if value, ok := filter.Labels["platform"]; ok {
|
||||
filter.Labels[pipelineConsts.LabelPlatform] = value
|
||||
delete(filter.Labels, "platform")
|
||||
}
|
||||
|
||||
if value, ok := filter.Labels["hostname"]; ok {
|
||||
filter.Labels[pipelineConsts.LabelHostname] = value
|
||||
delete(filter.Labels, "hostname")
|
||||
}
|
||||
|
||||
if value, ok := filter.Labels["backend"]; ok {
|
||||
filter.Labels[pipelineConsts.LabelBackend] = value
|
||||
delete(filter.Labels, "backend")
|
||||
}
|
||||
|
||||
if value, ok := filter.Labels["org-id"]; ok {
|
||||
filter.Labels[pipelineConsts.LabelOrgID] = value
|
||||
delete(filter.Labels, "org-id")
|
||||
}
|
||||
|
||||
return filter
|
||||
}
|
||||
|
||||
// Next blocks until it provides the next workflow to execute.
|
||||
func (s *RPC) Next(c context.Context, agentFilter rpc.Filter) (*rpc.Workflow, error) {
|
||||
if hostname, err := s.getHostnameFromContext(c); err == nil {
|
||||
log.Debug().Msgf("agent connected: %s: polling", hostname)
|
||||
}
|
||||
|
||||
agentFilter = migrateFilterLabels(agentFilter)
|
||||
|
||||
agent, err := s.getAgentFromContext(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -64,9 +64,9 @@ func (a *Agent) GetServerLabels() (map[string]string, error) {
|
||||
|
||||
// enforce filters for user and organization agents
|
||||
if a.OrgID != IDNotSet {
|
||||
filters[pipeline.LabelOrgID] = fmt.Sprintf("%d", a.OrgID)
|
||||
filters[pipeline.LabelFilterOrg] = fmt.Sprintf("%d", a.OrgID)
|
||||
} else {
|
||||
filters[pipeline.LabelOrgID] = "*"
|
||||
filters[pipeline.LabelFilterOrg] = "*"
|
||||
}
|
||||
|
||||
return filters, nil
|
||||
|
@ -38,7 +38,7 @@ func TestAgent_GetServerLabels(t *testing.T) {
|
||||
filters, err := agent.GetServerLabels()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, map[string]string{
|
||||
pipeline.LabelOrgID: "0",
|
||||
pipeline.LabelFilterOrg: "0",
|
||||
}, filters)
|
||||
})
|
||||
|
||||
@ -49,7 +49,7 @@ func TestAgent_GetServerLabels(t *testing.T) {
|
||||
filters, err := agent.GetServerLabels()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, map[string]string{
|
||||
pipeline.LabelOrgID: "*",
|
||||
pipeline.LabelFilterOrg: "*",
|
||||
}, filters)
|
||||
})
|
||||
|
||||
@ -60,7 +60,7 @@ func TestAgent_GetServerLabels(t *testing.T) {
|
||||
filters, err := agent.GetServerLabels()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, map[string]string{
|
||||
pipeline.LabelOrgID: "123",
|
||||
pipeline.LabelFilterOrg: "123",
|
||||
}, filters)
|
||||
})
|
||||
}
|
||||
|
@ -50,8 +50,8 @@ func (t *Task) ApplyLabelsFromRepo(r *Repo) error {
|
||||
if t.Labels == nil {
|
||||
t.Labels = make(map[string]string)
|
||||
}
|
||||
t.Labels[pipeline.LabelRepoFullName] = r.FullName
|
||||
t.Labels[pipeline.LabelOrgID] = fmt.Sprintf("%d", r.OrgID)
|
||||
t.Labels[pipeline.LabelFilterRepo] = r.FullName
|
||||
t.Labels[pipeline.LabelFilterOrg] = fmt.Sprintf("%d", r.OrgID)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,8 @@ func TestTask_GetLabels(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, task.Labels)
|
||||
assert.Equal(t, map[string]string{
|
||||
pipeline.LabelRepoFullName: "",
|
||||
pipeline.LabelOrgID: "0",
|
||||
pipeline.LabelFilterRepo: "",
|
||||
pipeline.LabelFilterOrg: "0",
|
||||
}, task.Labels)
|
||||
})
|
||||
|
||||
@ -59,8 +59,8 @@ func TestTask_GetLabels(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, task.Labels)
|
||||
assert.Equal(t, map[string]string{
|
||||
pipeline.LabelRepoFullName: "test/repo",
|
||||
pipeline.LabelOrgID: "456",
|
||||
pipeline.LabelFilterRepo: "test/repo",
|
||||
pipeline.LabelFilterOrg: "456",
|
||||
}, task.Labels)
|
||||
})
|
||||
|
||||
@ -81,9 +81,9 @@ func TestTask_GetLabels(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, task.Labels)
|
||||
assert.Equal(t, map[string]string{
|
||||
"existing": "label",
|
||||
pipeline.LabelRepoFullName: "test/repo",
|
||||
pipeline.LabelOrgID: "456",
|
||||
"existing": "label",
|
||||
pipeline.LabelFilterRepo: "test/repo",
|
||||
pipeline.LabelFilterOrg: "456",
|
||||
}, task.Labels)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user