From 27b2f3ab6d245dcc86cfd994699132a5cf90fdc4 Mon Sep 17 00:00:00 2001 From: Chun-Mao Lai <72752478+Mecoli1219@users.noreply.github.com> Date: Fri, 20 Dec 2024 03:47:17 -0800 Subject: [PATCH 01/15] [Docs] Add new page for jupyter notebook interactive mode (#6036) * test new nb-rli Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix error & debug Signed-off-by: Mecoli1219 * fix buf Signed-off-by: Mecoli1219 * update post Signed-off-by: Mecoli1219 * update clone path Signed-off-by: Mecoli1219 * update conf.py Signed-off-by: Mecoli1219 * update path Signed-off-by: Mecoli1219 * Update lines Signed-off-by: Mecoli1219 * Create a new page Signed-off-by: Mecoli1219 * test direct link & direct ipynb Signed-off-by: Mecoli1219 * test multiple possible solutions Signed-off-by: Mecoli1219 * Create a new page Signed-off-by: Mecoli1219 * Modify anchor Signed-off-by: Mecoli1219 * Fix anchor Signed-off-by: Mecoli1219 --------- Signed-off-by: Mecoli1219 --- docs/user_guide/flyte_fundamentals/index.md | 3 + .../jupyter_notebook_interaction.md | 91 +++++++++++++++++++ .../running_and_scheduling_workflows.md | 5 +- 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 docs/user_guide/flyte_fundamentals/jupyter_notebook_interaction.md diff --git a/docs/user_guide/flyte_fundamentals/index.md b/docs/user_guide/flyte_fundamentals/index.md index a1a08fd187..9ef8a5bd2b 100644 --- a/docs/user_guide/flyte_fundamentals/index.md +++ b/docs/user_guide/flyte_fundamentals/index.md @@ -22,6 +22,8 @@ use cases. - Develop and deploy workflows to a local Flyte demo cluster. * - {doc}`⏱ Running and scheduling workflows ` - Execute workflows programmatically and schedule them as cron jobs. +* - {doc}`📙 Jupyter notebook interaction ` + - Develop and debug Flyte workflows interactively in Jupyter notebooks. * - {doc}`📊 Visualizing task input and output ` - Create rich, customizable static reports for increased visibility into tasks. * - {doc}`🏎 Optimizing tasks ` @@ -45,6 +47,7 @@ cluster, see the {ref}`Deployment Guide `. tasks_workflows_and_launch_plans registering_workflows running_and_scheduling_workflows +jupyter_notebook_interaction visualizing_task_input_and_output optimizing_tasks extending_flyte diff --git a/docs/user_guide/flyte_fundamentals/jupyter_notebook_interaction.md b/docs/user_guide/flyte_fundamentals/jupyter_notebook_interaction.md new file mode 100644 index 0000000000..7d11828304 --- /dev/null +++ b/docs/user_guide/flyte_fundamentals/jupyter_notebook_interaction.md @@ -0,0 +1,91 @@ +--- +kernelspec: + display_name: Python 3 + language: python + name: python3 +--- + +(getting_started_jupyter_notebook_interaction)= + +# Running and developing workflows in Jupyter notebooks + +Flyte supports the development, running, and debugging of tasks and workflows in an interactive +Jupyter notebook environment, which accelerates the iteration speed when building data- +or machine learning-driven applications. + +```{admonition} Attention +:class: attention + +This feature requires the `flytekit` version `1.14.0` or higher. +``` + +```{admonition} Prerequisites +:class: important + +This guide assumes that you've completed the previous guides for +{ref}`Running and Scheduling Workflows `. +The code snippets in this guide are intended to be run in a Jupyter notebook. +``` + +The code of this guide can be found in the [flytesnacks](https://github.com/flyteorg/flytesnacks/blob/master/examples/basics/basics/basic_interactive_mode.ipynb) + +## Create an interactive `FlyteRemote` object + +In {ref}`Running and Scheduling Workflows `, you learned +how to run registered Flyte workflows from a Python runtime using the +{py:class}`~flytekit.remote.remote.FlyteRemote` client. + +When developing workflows in a Jupyter notebook, `FlyteRemote` provides an +interactive interface to register and run workflows on a Flyte cluster. Let's +create an interactive `FlyteRemote` object: + +```{code-cell} ipython3 +:tags: [remove-output] + +from flytekit.configuration import Config +from flytekit.remote import FlyteRemote + +remote = FlyteRemote( + config=Config.auto(), + default_project="flytesnacks", + default_domain="development", + interactive_mode_enabled=True, +) +``` + +```{admonition} Note +:class: Note + +The `interactive_mode_enabled` flag is automatically set to `True` when running +in a Jupyter notebook environment, enabling interactive registration and execution +of workflows. +``` + +## Running a task or a workflow + +You can run entities (tasks or workflows) using the `FlyteRemote` +{py:meth}`~flytekit.remote.remote.FlyteRemote.execute` method. +During execution, `flytekit` first checks if the entity is registered with the +Flyte backend, and if not, registers it before execution. + +```{code-block} python +execution = remote.execute(my_task, inputs={"name": "Flyte"}) +execution = remote.execute(my_wf, inputs={"name": "Flyte"}) +``` + +You can then fetch the inputs and outputs of the execution by following the steps +in {ref}`getting_started_run_and_schedule_fetch_execution`. + +## When Does Interactive `FlyteRemote` Re-register an Entity? + +The interactive `FlyteRemote` client re-registers an entity whenever it's +redefined in the notebook, including when you re-execute a cell containing the +entity definition, even if the entity remains unchanged. This behavior facilitates +iterative development and debugging of tasks and workflows in a Jupyter notebook. + +## What's next? + +In this guide, you learned how to develop and run tasks and workflows in a +Jupyter Notebook environment using interactive `FlyteRemote`. + +In the next guide, you'll learn how to visualize tasks using Flyte Decks. diff --git a/docs/user_guide/flyte_fundamentals/running_and_scheduling_workflows.md b/docs/user_guide/flyte_fundamentals/running_and_scheduling_workflows.md index 60bbe98596..4a552a1275 100644 --- a/docs/user_guide/flyte_fundamentals/running_and_scheduling_workflows.md +++ b/docs/user_guide/flyte_fundamentals/running_and_scheduling_workflows.md @@ -184,6 +184,8 @@ execution = remote.execute(flyte_task, inputs={"name": "Kermit"}) You can also launch tasks via `flytectl`, learn more in the {ref}`User Guide ` ``` +(getting_started_run_and_schedule_fetch_execution)= + ## Fetching inputs and outputs of an execution By default, {py:meth}`FlyteRemote.execute ` @@ -342,4 +344,5 @@ In this guide, you learned about how to: - Run tasks, workflows, and launch plans using `FlyteRemote`. - Create a cron schedule to run a launch plan at a specified time interval. -In the next guide, you'll learn how to visualize tasks using Flyte Decks. +In the next guide, you'll learn how to develop and run tasks and workflows in +a Jupyter Notebook environment. From 4ac3019f88ea8137403b35672b4510078c30b509 Mon Sep 17 00:00:00 2001 From: Andrew Dye Date: Fri, 20 Dec 2024 11:16:20 -0800 Subject: [PATCH 02/15] Use child dir for branch taken (#6120) We reuse the same data directory for the branch node and the branch taken (child). This change adds an additional set of directories to decouple these. It makes sure to copy the child output up to the branch node output like we do in subworkflow Example ``` from dataclasses import dataclass from flytekit import conditional, task, workflow @dataclass class MyData: foo: str @workflow def root_wf(data: MyData) -> str: return sub_wf(data=data) @workflow def sub_wf(data: MyData) -> str: check = always_true() return conditional("decision").if_(check.is_true()).then(conditional_wf(data=data)).else_().fail("not done") @task def always_true() -> bool: return True @workflow def conditional_wf(data: MyData) -> str: return done(data) @task def done(data: MyData) -> str: return f"done ({data.foo})" ``` - [x] Add unittests - [x] Run locally using sandbox and verify behavior with working example. Inspect paths Signed-off-by: Andrew Dye --- .../pkg/controller/nodes/branch/handler.go | 31 +++++++++++++------ .../controller/nodes/branch/handler_test.go | 31 ++++++++++--------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/flytepropeller/pkg/controller/nodes/branch/handler.go b/flytepropeller/pkg/controller/nodes/branch/handler.go index 9789b65c22..a869569680 100644 --- a/flytepropeller/pkg/controller/nodes/branch/handler.go +++ b/flytepropeller/pkg/controller/nodes/branch/handler.go @@ -3,6 +3,7 @@ package branch import ( "context" "fmt" + "strconv" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" "github.com/flyteorg/flyte/flytepropeller/pkg/apis/flyteworkflow/v1alpha1" @@ -15,6 +16,7 @@ import ( stdErrors "github.com/flyteorg/flyte/flytestdlib/errors" "github.com/flyteorg/flyte/flytestdlib/logger" "github.com/flyteorg/flyte/flytestdlib/promutils" + "github.com/flyteorg/flyte/flytestdlib/storage" ) type metrics struct { @@ -74,8 +76,7 @@ func (b *branchHandler) HandleBranchNode(ctx context.Context, branchNode v1alpha childNodeStatus.SetParentNodeID(&i) logger.Debugf(ctx, "Recursively executing branchNode's chosen path") - nodeStatus := nl.GetNodeExecutionStatus(ctx, nCtx.NodeID()) - return b.recurseDownstream(ctx, nCtx, nodeStatus, finalNode) + return b.recurseDownstream(ctx, nCtx, finalNode) } // If the branchNodestatus was already evaluated i.e, Node is in Running status @@ -99,8 +100,7 @@ func (b *branchHandler) HandleBranchNode(ctx context.Context, branchNode v1alpha } // Recurse downstream - nodeStatus := nl.GetNodeExecutionStatus(ctx, nCtx.NodeID()) - return b.recurseDownstream(ctx, nCtx, nodeStatus, branchTakenNode) + return b.recurseDownstream(ctx, nCtx, branchTakenNode) } func (b *branchHandler) Handle(ctx context.Context, nCtx interfaces.NodeExecutionContext) (handler.Transition, error) { @@ -123,7 +123,7 @@ func (b *branchHandler) getExecutionContextForDownstream(nCtx interfaces.NodeExe return executors.NewExecutionContextWithParentInfo(nCtx.ExecutionContext(), newParentInfo), nil } -func (b *branchHandler) recurseDownstream(ctx context.Context, nCtx interfaces.NodeExecutionContext, nodeStatus v1alpha1.ExecutableNodeStatus, branchTakenNode v1alpha1.ExecutableNode) (handler.Transition, error) { +func (b *branchHandler) recurseDownstream(ctx context.Context, nCtx interfaces.NodeExecutionContext, branchTakenNode v1alpha1.ExecutableNode) (handler.Transition, error) { // TODO we should replace the call to RecursiveNodeHandler with a call to SingleNode Handler. The inputs are also already known ahead of time // There is no DAGStructure for the branch nodes, the branch taken node is the leaf node. The node itself may be arbitrarily complex, but in that case the node should reference a subworkflow etc // The parent of the BranchTaken Node is the actual Branch Node and all the data is just forwarded from the Branch to the executed node. @@ -134,8 +134,16 @@ func (b *branchHandler) recurseDownstream(ctx context.Context, nCtx interfaces.N } childNodeStatus := nl.GetNodeExecutionStatus(ctx, branchTakenNode.GetID()) - childNodeStatus.SetDataDir(nodeStatus.GetDataDir()) - childNodeStatus.SetOutputDir(nodeStatus.GetOutputDir()) + childDataDir, err := nCtx.DataStore().ConstructReference(ctx, nCtx.NodeStatus().GetOutputDir(), branchTakenNode.GetID()) + if err != nil { + return handler.UnknownTransition, err + } + childOutputDir, err := nCtx.DataStore().ConstructReference(ctx, childDataDir, strconv.Itoa(int(childNodeStatus.GetAttempts()))) + if err != nil { + return handler.UnknownTransition, err + } + childNodeStatus.SetDataDir(childDataDir) + childNodeStatus.SetOutputDir(childOutputDir) upstreamNodeIds, err := nCtx.ContextualNodeLookup().ToNode(branchTakenNode.GetID()) if err != nil { return handler.UnknownTransition, err @@ -151,9 +159,14 @@ func (b *branchHandler) recurseDownstream(ctx context.Context, nCtx interfaces.N } if downstreamStatus.IsComplete() { - // For branch node we set the output node to be the same as the child nodes output + childOutputsPath := v1alpha1.GetOutputsFile(childOutputDir) + outputsPath := v1alpha1.GetOutputsFile(nCtx.NodeStatus().GetOutputDir()) + if err := nCtx.DataStore().CopyRaw(ctx, childOutputsPath, outputsPath, storage.Options{}); err != nil { + errMsg := fmt.Sprintf("Failed to copy child node outputs from [%v] to [%v]", childOutputsPath, outputsPath) + return handler.DoTransition(handler.TransitionTypeEphemeral, handler.PhaseInfoFailure(core.ExecutionError_SYSTEM, errors.OutputsNotFoundError, errMsg, nil)), nil + } phase := handler.PhaseInfoSuccess(&handler.ExecutionInfo{ - OutputInfo: &handler.OutputInfo{OutputURI: v1alpha1.GetOutputsFile(childNodeStatus.GetOutputDir())}, + OutputInfo: &handler.OutputInfo{OutputURI: outputsPath}, }) return handler.DoTransition(handler.TransitionTypeEphemeral, phase), nil diff --git a/flytepropeller/pkg/controller/nodes/branch/handler_test.go b/flytepropeller/pkg/controller/nodes/branch/handler_test.go index a48344020d..96d20b1710 100644 --- a/flytepropeller/pkg/controller/nodes/branch/handler_test.go +++ b/flytepropeller/pkg/controller/nodes/branch/handler_test.go @@ -1,6 +1,7 @@ package branch import ( + "bytes" "context" "fmt" "testing" @@ -110,6 +111,7 @@ func createNodeContext(phase v1alpha1.BranchNodePhase, childNodeID *v1alpha1.Nod ns := &mocks2.ExecutableNodeStatus{} ns.OnGetDataDir().Return(storage.DataReference("data-dir")) + ns.OnGetOutputDir().Return(storage.DataReference("output-dir")) ns.OnGetPhase().Return(v1alpha1.NodePhaseNotYetStarted) ir := &mocks3.InputReader{} @@ -162,7 +164,6 @@ func TestBranchHandler_RecurseDownstream(t *testing.T) { name string ns interfaces.NodeStatus err error - nodeStatus *mocks2.ExecutableNodeStatus branchTakenNode v1alpha1.ExecutableNode isErr bool expectedPhase handler.EPhase @@ -170,17 +171,17 @@ func TestBranchHandler_RecurseDownstream(t *testing.T) { upstreamNodeID string }{ {"upstreamNodeExists", interfaces.NodeStatusPending, nil, - &mocks2.ExecutableNodeStatus{}, bn, false, handler.EPhaseRunning, v1alpha1.NodePhaseQueued, "n2"}, + bn, false, handler.EPhaseRunning, v1alpha1.NodePhaseQueued, "n2"}, {"childNodeError", interfaces.NodeStatusUndefined, fmt.Errorf("err"), - &mocks2.ExecutableNodeStatus{}, bn, true, handler.EPhaseUndefined, v1alpha1.NodePhaseFailed, ""}, + bn, true, handler.EPhaseUndefined, v1alpha1.NodePhaseFailed, ""}, {"childPending", interfaces.NodeStatusPending, nil, - &mocks2.ExecutableNodeStatus{}, bn, false, handler.EPhaseRunning, v1alpha1.NodePhaseQueued, ""}, + bn, false, handler.EPhaseRunning, v1alpha1.NodePhaseQueued, ""}, {"childStillRunning", interfaces.NodeStatusRunning, nil, - &mocks2.ExecutableNodeStatus{}, bn, false, handler.EPhaseRunning, v1alpha1.NodePhaseRunning, ""}, + bn, false, handler.EPhaseRunning, v1alpha1.NodePhaseRunning, ""}, {"childFailure", interfaces.NodeStatusFailed(expectedError), nil, - &mocks2.ExecutableNodeStatus{}, bn, false, handler.EPhaseFailed, v1alpha1.NodePhaseFailed, ""}, + bn, false, handler.EPhaseFailed, v1alpha1.NodePhaseFailed, ""}, {"childComplete", interfaces.NodeStatusComplete, nil, - &mocks2.ExecutableNodeStatus{}, bn, false, handler.EPhaseSuccess, v1alpha1.NodePhaseSucceeded, ""}, + bn, false, handler.EPhaseSuccess, v1alpha1.NodePhaseSucceeded, ""}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -222,16 +223,16 @@ func TestBranchHandler_RecurseDownstream(t *testing.T) { ).Return(test.ns, test.err) childNodeStatus := &mocks2.ExecutableNodeStatus{} - if mockNodeLookup != nil { - childNodeStatus.OnGetOutputDir().Return("parent-output-dir") - test.nodeStatus.OnGetDataDir().Return("parent-data-dir") - test.nodeStatus.OnGetOutputDir().Return("parent-output-dir") - mockNodeLookup.OnGetNodeExecutionStatus(ctx, childNodeID).Return(childNodeStatus) - childNodeStatus.On("SetDataDir", storage.DataReference("parent-data-dir")).Once() - childNodeStatus.On("SetOutputDir", storage.DataReference("parent-output-dir")).Once() + childNodeStatus.OnGetAttempts().Return(0) + childNodeStatus.On("SetDataDir", storage.DataReference("/output-dir/child")).Once() + childNodeStatus.On("SetOutputDir", storage.DataReference("/output-dir/child/0")).Once() + mockNodeLookup.OnGetNodeExecutionStatus(ctx, childNodeID).Return(childNodeStatus) + if test.childPhase == v1alpha1.NodePhaseSucceeded { + _ = nCtx.DataStore().WriteRaw(ctx, storage.DataReference("/output-dir/child/0/outputs.pb"), 0, storage.Options{}, bytes.NewReader([]byte{})) } + branch := New(mockNodeExecutor, eventConfig, promutils.NewTestScope()).(*branchHandler) - h, err := branch.recurseDownstream(ctx, nCtx, test.nodeStatus, test.branchTakenNode) + h, err := branch.recurseDownstream(ctx, nCtx, test.branchTakenNode) if test.isErr { assert.Error(t, err) } else { From 691bde5fea5c0f26efa29de5815dad6cf367dac8 Mon Sep 17 00:00:00 2001 From: Flyte Bot Date: Mon, 23 Dec 2024 13:09:37 -0800 Subject: [PATCH 03/15] [auto-update-contributors] update all-contributors (#6047) Signed-off-by: Flyte Bot Co-authored-by: kumare3 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5f2aab54f..ab094d5da5 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ There are many ways to get involved in Flyte, including: ### We :heart: our contributors -[![953358](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/953358?v=4&w=50&h=50&mask=circle)](https://github.com/katrogan)[![37090125](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37090125?v=4&w=50&h=50&mask=circle)](https://github.com/lyft-metaservice-3)[![7597118](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7597118?v=4&w=50&h=50&mask=circle)](https://github.com/matthewphsmith)[![27159](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27159?v=4&w=50&h=50&mask=circle)](https://github.com/EngHabu)[![29843943](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/29843943?v=4&w=50&h=50&mask=circle)](https://github.com/goreleaserbot)[![8888115](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8888115?v=4&w=50&h=50&mask=circle)](https://github.com/hamersaw)[![10830562](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10830562?v=4&w=50&h=50&mask=circle)](https://github.com/yindia)[![78108056](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/78108056?v=4&w=50&h=50&mask=circle)](https://github.com/flyte-bot)[![158892](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/158892?v=4&w=50&h=50&mask=circle)](https://github.com/honnix)[![18408237](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18408237?v=4&w=50&h=50&mask=circle)](https://github.com/anandswaminathan)[![2896568](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2896568?v=4&w=50&h=50&mask=circle)](https://github.com/wild-endeavor)[![37936015](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37936015?v=4&w=50&h=50&mask=circle)](https://github.com/pingsutw)[![653394](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/653394?v=4&w=50&h=50&mask=circle)](https://github.com/eapolinario)[![1518524](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1518524?v=4&w=50&h=50&mask=circle)](https://github.com/bnsblue)[![27724763](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27724763?v=4&w=50&h=50&mask=circle)](https://github.com/iaroslav-ciupin)[![16888709](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16888709?v=4&w=50&h=50&mask=circle)](https://github.com/kumare3)[![27777173](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27777173?v=4&w=50&h=50&mask=circle)](https://github.com/samhita-alla)[![23062603](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23062603?v=4&w=50&h=50&mask=circle)](https://github.com/Antaxify)[![77798312](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/77798312?v=4&w=50&h=50&mask=circle)](https://github.com/pmahindrakar-oss)[![5032356](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5032356?v=4&w=50&h=50&mask=circle)](https://github.com/brucearctor)[![8805803](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8805803?v=4&w=50&h=50&mask=circle)](https://github.com/alexlipa91)[![6239450](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6239450?v=4&w=50&h=50&mask=circle)](https://github.com/mayitbeegh)[![452166](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/452166?v=4&w=50&h=50&mask=circle)](https://github.com/MorpheusXAUT)[![15335863](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/15335863?v=4&w=50&h=50&mask=circle)](https://github.com/gvashishtha)[![6562898](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6562898?v=4&w=50&h=50&mask=circle)](https://github.com/ckiosidis)[![4748985](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4748985?v=4&w=50&h=50&mask=circle)](https://github.com/aliabbasjaffri)[![76461262](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/76461262?v=4&w=50&h=50&mask=circle)](https://github.com/Future-Outlier)[![5725707](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5725707?v=4&w=50&h=50&mask=circle)](https://github.com/andrewwdye)[![8122852](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8122852?v=4&w=50&h=50&mask=circle)](https://github.com/ariefrahmansyah)[![10869815](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10869815?v=4&w=50&h=50&mask=circle)](https://github.com/jeevb)[![3880645](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3880645?v=4&w=50&h=50&mask=circle)](https://github.com/jonathanburns)[![3936213](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3936213?v=4&w=50&h=50&mask=circle)](https://github.com/lu4nm3)[![26174213](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26174213?v=4&w=50&h=50&mask=circle)](https://github.com/lyft-metaservice-2)[![126913098](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/126913098?v=4&w=50&h=50&mask=circle)](https://github.com/squiishyy)[![46989299](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46989299?v=4&w=50&h=50&mask=circle)](https://github.com/supreeth7)[![1815175](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1815175?v=4&w=50&h=50&mask=circle)](https://github.com/schottra)[![37558497](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37558497?v=4&w=50&h=50&mask=circle)](https://github.com/pvditt)[![5487021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5487021?v=4&w=50&h=50&mask=circle)](https://github.com/veggiemonk)[![9142716](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9142716?v=4&w=50&h=50&mask=circle)](https://github.com/2uasimojo)[![2816689](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2816689?v=4&w=50&h=50&mask=circle)](https://github.com/cosmicBboy)[![19375241](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19375241?v=4&w=50&h=50&mask=circle)](https://github.com/migueltol22)[![24364830](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24364830?v=4&w=50&h=50&mask=circle)](https://github.com/ByronHsu)[![53313394](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/53313394?v=4&w=50&h=50&mask=circle)](https://github.com/kosigz-lyft)[![43610471](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43610471?v=4&w=50&h=50&mask=circle)](https://github.com/yk-x-25)[![10526540](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10526540?v=4&w=50&h=50&mask=circle)](https://github.com/yubofredwang)[![16090976](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16090976?v=4&w=50&h=50&mask=circle)](https://github.com/surindersinghp)[![94349093](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/94349093?v=4&w=50&h=50&mask=circle)](https://github.com/SmritiSatyanV)[![70988](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/70988?v=4&w=50&h=50&mask=circle)](https://github.com/slai)[![6065051](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6065051?v=4&w=50&h=50&mask=circle)](https://github.com/milton0825)[![38207208](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/38207208?v=4&w=50&h=50&mask=circle)](https://github.com/tnsetting)[![95110820](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/95110820?v=4&w=50&h=50&mask=circle)](https://github.com/jerempy)[![11799671](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11799671?v=4&w=50&h=50&mask=circle)](https://github.com/bstadlbauer)[![34587798](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/34587798?v=4&w=50&h=50&mask=circle)](https://github.com/akhurana001)[![5026554](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5026554?v=4&w=50&h=50&mask=circle)](https://github.com/vsbus)[![1472826](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1472826?v=4&w=50&h=50&mask=circle)](https://github.com/maximsmol)[![31255434](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31255434?v=4&w=50&h=50&mask=circle)](https://github.com/kennyworkman)[![1330233](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1330233?v=4&w=50&h=50&mask=circle)](https://github.com/igorvalko)[![248688](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/248688?v=4&w=50&h=50&mask=circle)](https://github.com/hanzo)[![467927](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/467927?v=4&w=50&h=50&mask=circle)](https://github.com/kanterov)[![36511035](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36511035?v=4&w=50&h=50&mask=circle)](https://github.com/fg91)[![4967458](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4967458?v=4&w=50&h=50&mask=circle)](https://github.com/chanadian)[![8200209](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8200209?v=4&w=50&h=50&mask=circle)](https://github.com/catalinii)[![43587819](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43587819?v=4&w=50&h=50&mask=circle)](https://github.com/chetcode)[![163899](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/163899?v=4&w=50&h=50&mask=circle)](https://github.com/regadas)[![54248170](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54248170?v=4&w=50&h=50&mask=circle)](https://github.com/nicholasjng)[![2538760](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2538760?v=4&w=50&h=50&mask=circle)](https://github.com/akumor)[![104257](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/104257?v=4&w=50&h=50&mask=circle)](https://github.com/flixr)[![92917168](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/92917168?v=4&w=50&h=50&mask=circle)](https://github.com/edwinyyyu)[![1360529](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1360529?v=4&w=50&h=50&mask=circle)](https://github.com/clairemcginty)[![1777447](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1777447?v=4&w=50&h=50&mask=circle)](https://github.com/goyalankit)[![1316881](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1316881?v=4&w=50&h=50&mask=circle)](https://github.com/akashkatipally)[![22784654](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22784654?v=4&w=50&h=50&mask=circle)](https://github.com/aybidi)[![5402633](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5402633?v=4&w=50&h=50&mask=circle)](https://github.com/thomasjpfan)[![49699333](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/29110?v=4&w=50&h=50&mask=circle)](https://github.com/apps/dependabot)[![72752478](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/72752478?v=4&w=50&h=50&mask=circle)](https://github.com/Mecoli1219)[![19733683](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19733683?v=4&w=50&h=50&mask=circle)](https://github.com/snyk-bot)[![114708546](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/114708546?v=4&w=50&h=50&mask=circle)](https://github.com/troychiu)[![35886692](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/35886692?v=4&w=50&h=50&mask=circle)](https://github.com/austin362667)[![47914085](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/47914085?v=4&w=50&h=50&mask=circle)](https://github.com/MortalHappiness)[![9131935](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9131935?v=4&w=50&h=50&mask=circle)](https://github.com/Tom-Newton)[![155087](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/155087?v=4&w=50&h=50&mask=circle)](https://github.com/derwiki)[![40698988](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/40698988?v=4&w=50&h=50&mask=circle)](https://github.com/dansola)[![14800485](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14800485?v=4&w=50&h=50&mask=circle)](https://github.com/jasonlai1218)[![62143443](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/62143443?v=4&w=50&h=50&mask=circle)](https://github.com/mao3267)[![31577879](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31577879?v=4&w=50&h=50&mask=circle)](https://github.com/pryce-turner)[![1399455](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1399455?v=4&w=50&h=50&mask=circle)](https://github.com/th0114nd)[![58504997](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/58504997?v=4&w=50&h=50&mask=circle)](https://github.com/novahow)[![46030368](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46030368?v=4&w=50&h=50&mask=circle)](https://github.com/ChungYujoyce)[![21109744](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/21109744?v=4&w=50&h=50&mask=circle)](https://github.com/AlekhyaSasi)[![1810591](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1810591?v=4&w=50&h=50&mask=circle)](https://github.com/asottile)[![54340816](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54340816?v=4&w=50&h=50&mask=circle)](https://github.com/granthamtaylor)[![89976021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/89976021?v=4&w=50&h=50&mask=circle)](https://github.com/fiedlerNr9)[![51814063](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/51814063?v=4&w=50&h=50&mask=circle)](https://github.com/Yicheng-Lu-llll)[![9609986](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9609986?v=4&w=50&h=50&mask=circle)](https://github.com/sonjaer)[![1153481](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1153481?v=4&w=50&h=50&mask=circle)](https://github.com/ppiegaze)[![35151789](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/35151789?v=4&w=50&h=50&mask=circle)](https://github.com/ggydush)[![140021987](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/140021987?v=4&w=50&h=50&mask=circle)](https://github.com/ddl-rliu)[![138256885](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/138256885?v=4&w=50&h=50&mask=circle)](https://github.com/ysysys3074)[![3939659](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3939659?v=4&w=50&h=50&mask=circle)](https://github.com/sbrunk)[![80421934](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/80421934?v=4&w=50&h=50&mask=circle)](https://github.com/SandraGH5)[![52046377](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/52046377?v=4&w=50&h=50&mask=circle)](https://github.com/hhcs9527)[![4406268](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4406268?v=4&w=50&h=50&mask=circle)](https://github.com/otarabai)[![16709018](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16709018?v=4&w=50&h=50&mask=circle)](https://github.com/noahjax)[![417209](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/417209?v=4&w=50&h=50&mask=circle)](https://github.com/neverett)[![27844407](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27844407?v=4&w=50&h=50&mask=circle)](https://github.com/ringohoffman)[![106939297](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/106939297?v=4&w=50&h=50&mask=circle)](https://github.com/chaohengstudent)[![380854](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/380854?v=4&w=50&h=50&mask=circle)](https://github.com/bgedik)[![18337807](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18337807?v=4&w=50&h=50&mask=circle)](https://github.com/max-hoffman)[![1276867](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1276867?v=4&w=50&h=50&mask=circle)](https://github.com/JackUrb)[![115421902](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/115421902?v=4&w=50&h=50&mask=circle)](https://github.com/wayner0628)[![36886416](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36886416?v=4&w=50&h=50&mask=circle)](https://github.com/JiangJiaWei1103)[![134093844](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/134093844?v=4&w=50&h=50&mask=circle)](https://github.com/rdeaton-freenome)[![106936600](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/106936600?v=4&w=50&h=50&mask=circle)](https://github.com/peridotml)[![26268253](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26268253?v=4&w=50&h=50&mask=circle)](https://github.com/arbaobao)[![16509490](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16509490?v=4&w=50&h=50&mask=circle)](https://github.com/ryankarlos)[![98242479](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/98242479?v=4&w=50&h=50&mask=circle)](https://github.com/RichhLi)[![98349643](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/98349643?v=4&w=50&h=50&mask=circle)](https://github.com/rahul-theorem)[![12219405](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12219405?v=4&w=50&h=50&mask=circle)](https://github.com/fediazgon)[![322624](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/322624?v=4&w=50&h=50&mask=circle)](https://github.com/AdrianoKF)[![953385](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/953385?v=4&w=50&h=50&mask=circle)](https://github.com/blaketastic2)[![30375389](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/30375389?v=4&w=50&h=50&mask=circle)](https://github.com/bimtauer)[![92072956](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/92072956?v=4&w=50&h=50&mask=circle)](https://github.com/PudgyPigeon)[![97543480](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/97543480?v=4&w=50&h=50&mask=circle)](https://github.com/esadler-hbo)[![69013027](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/69013027?v=4&w=50&h=50&mask=circle)](https://github.com/ggydush-fn)[![116700206](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/116700206?v=4&w=50&h=50&mask=circle)](https://github.com/kiliangojek)[![1521126](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1521126?v=4&w=50&h=50&mask=circle)](https://github.com/pbrogan12)[![120470035](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/120470035?v=4&w=50&h=50&mask=circle)](https://github.com/redartera)[![4025771](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4025771?v=4&w=50&h=50&mask=circle)](https://github.com/andresgomezfrr)[![422486](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/422486?v=4&w=50&h=50&mask=circle)](https://github.com/bethebunny)[![26092524](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26092524?v=4&w=50&h=50&mask=circle)](https://github.com/fellhorn)[![1168692](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1168692?v=4&w=50&h=50&mask=circle)](https://github.com/dennisobrien)[![33652917](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/33652917?v=4&w=50&h=50&mask=circle)](https://github.com/hfurkanvural)[![45017130](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/45017130?v=4&w=50&h=50&mask=circle)](https://github.com/helenzhangyc)[![1659910](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1659910?v=4&w=50&h=50&mask=circle)](https://github.com/oliverhu)[![91385411](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/91385411?v=4&w=50&h=50&mask=circle)](https://github.com/Ln11211)[![30621230](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/30621230?v=4&w=50&h=50&mask=circle)](https://github.com/aeioulisa)[![54334265](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54334265?v=4&w=50&h=50&mask=circle)](https://github.com/michaels-lyft)[![48736656](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48736656?v=4&w=50&h=50&mask=circle)](https://github.com/murilommen)[![150836163](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/150836163?v=4&w=50&h=50&mask=circle)](https://github.com/neilisaur)[![17165004](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17165004?v=4&w=50&h=50&mask=circle)](https://github.com/RobertoRRW)[![81233629](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/81233629?v=4&w=50&h=50&mask=circle)](https://github.com/101rakibulhasan)[![38955457](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/38955457?v=4&w=50&h=50&mask=circle)](https://github.com/RRK1000)[![2614101](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2614101?v=4&w=50&h=50&mask=circle)](https://github.com/RobinKa)[![4308533](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4308533?v=4&w=50&h=50&mask=circle)](https://github.com/rubenbarragan)[![10201242](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10201242?v=4&w=50&h=50&mask=circle)](https://github.com/sugatoray)[![11269256](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11269256?v=4&w=50&h=50&mask=circle)](https://github.com/sushrut111)[![61228633](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/61228633?v=4&w=50&h=50&mask=circle)](https://github.com/Tat-V)[![13070236](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13070236?v=4&w=50&h=50&mask=circle)](https://github.com/TeoZosa)[![8817639](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8817639?v=4&w=50&h=50&mask=circle)](https://github.com/ThomVett)[![17309187](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17309187?v=4&w=50&h=50&mask=circle)](https://github.com/datability-io)[![2640499](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2640499?v=4&w=50&h=50&mask=circle)](https://github.com/wirthual)[![97332401](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/97332401?v=4&w=50&h=50&mask=circle)](https://github.com/RaghavMangla)[![100569684](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/100569684?v=4&w=50&h=50&mask=circle)](https://github.com/RRap0so)[![147648834](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/147648834?v=4&w=50&h=50&mask=circle)](https://github.com/quinten-flwls)[![37170063](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37170063?v=4&w=50&h=50&mask=circle)](https://github.com/Qiwen-Yu)[![43886578](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43886578?v=4&w=50&h=50&mask=circle)](https://github.com/400Ping)[![125105](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/125105?v=4&w=50&h=50&mask=circle)](https://github.com/tekumara)[![37547264](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37547264?v=4&w=50&h=50&mask=circle)](https://github.com/Nan2018)[![49385643](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49385643?v=4&w=50&h=50&mask=circle)](https://github.com/MinuraPunchihewa)[![10376195](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10376195?v=4&w=50&h=50&mask=circle)](https://github.com/myz540)[![4417105](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4417105?v=4&w=50&h=50&mask=circle)](https://github.com/Terryhung)[![73247359](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/73247359?v=4&w=50&h=50&mask=circle)](https://github.com/stef-stripe)[![12913704](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12913704?v=4&w=50&h=50&mask=circle)](https://github.com/mg515)[![119345186](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/119345186?v=4&w=50&h=50&mask=circle)](https://github.com/mcloney-ddm)[![13331724](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13331724?v=4&w=50&h=50&mask=circle)](https://github.com/martinlyra)[![24611279](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24611279?v=4&w=50&h=50&mask=circle)](https://github.com/ericwudayi)[![6333870](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6333870?v=4&w=50&h=50&mask=circle)](https://github.com/demmerichs)[![4023015](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4023015?v=4&w=50&h=50&mask=circle)](https://github.com/pradithya)[![12450632](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12450632?v=4&w=50&h=50&mask=circle)](https://github.com/ajsalow)[![3741621](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3741621?v=4&w=50&h=50&mask=circle)](https://github.com/palchicz)[![43726198](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43726198?v=4&w=50&h=50&mask=circle)](https://github.com/yundai424)[![131146298](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/131146298?v=4&w=50&h=50&mask=circle)](https://github.com/yini7777)[![29053051](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/29053051?v=4&w=50&h=50&mask=circle)](https://github.com/XinEDprob)[![52355146](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/52355146?v=4&w=50&h=50&mask=circle)](https://github.com/lowc1012)[![40901950](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/40901950?v=4&w=50&h=50&mask=circle)](https://github.com/WebOfNakedFancies)[![67166843](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/67166843?v=4&w=50&h=50&mask=circle)](https://github.com/vvasavada-fn)[![15071835](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/15071835?v=4&w=50&h=50&mask=circle)](https://github.com/va6996)[![3391550](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3391550?v=4&w=50&h=50&mask=circle)](https://github.com/devictr)[![57967031](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/57967031?v=4&w=50&h=50&mask=circle)](https://github.com/varshaparthay)[![5092599](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5092599?v=4&w=50&h=50&mask=circle)](https://github.com/vchowdhary)[![26834658](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26834658?v=4&w=50&h=50&mask=circle)](https://github.com/techytushar)[![14007150](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14007150?v=4&w=50&h=50&mask=circle)](https://github.com/deepyaman)[![2380665](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2380665?v=4&w=50&h=50&mask=circle)](https://github.com/DavidMertz)[![16297104](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16297104?v=4&w=50&h=50&mask=circle)](https://github.com/danpf)[![10463690](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10463690?v=4&w=50&h=50&mask=circle)](https://github.com/cjidboon94)[![26920893](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26920893?v=4&w=50&h=50&mask=circle)](https://github.com/chinghongfang)[![27000005](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27000005?v=4&w=50&h=50&mask=circle)](https://github.com/supercharleszhu)[![420942](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/420942?v=4&w=50&h=50&mask=circle)](https://github.com/cameronraysmith)[![6288302](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6288302?v=4&w=50&h=50&mask=circle)](https://github.com/CalvinLeather)[![179035736](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/179035736?v=4&w=50&h=50&mask=circle)](https://github.com/bryan-hunted)[![4396228](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4396228?v=4&w=50&h=50&mask=circle)](https://github.com/bryanwweber)[![7422223](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7422223?v=4&w=50&h=50&mask=circle)](https://github.com/bcvanmeurs)[![234145](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/234145?v=4&w=50&h=50&mask=circle)](https://github.com/benoistlaurent)[![31381038](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31381038?v=4&w=50&h=50&mask=circle)](https://github.com/lordnodd)[![49250723](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49250723?v=4&w=50&h=50&mask=circle)](https://github.com/ArthurBook)[![58334441](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/58334441?v=4&w=50&h=50&mask=circle)](https://github.com/wckdman)[![23013825](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23013825?v=4&w=50&h=50&mask=circle)](https://github.com/arpitbhardwaj)[![77167782](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/77167782?v=4&w=50&h=50&mask=circle)](https://github.com/apatel-fn)[![48966647](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48966647?v=4&w=50&h=50&mask=circle)](https://github.com/asahalyft)[![7005765](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7005765?v=4&w=50&h=50&mask=circle)](https://github.com/convexquad)[![54333860](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54333860?v=4&w=50&h=50&mask=circle)](https://github.com/aalavian)[![110886184](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/110886184?v=4&w=50&h=50&mask=circle)](https://github.com/aditya7302)[![19853373](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19853373?v=4&w=50&h=50&mask=circle)](https://github.com/NotMatthewGriffin)[![34498039](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/34498039?v=4&w=50&h=50&mask=circle)](https://github.com/matheusMoreno)[![20173739](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20173739?v=4&w=50&h=50&mask=circle)](https://github.com/madhur-tandon)[![4410453](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4410453?v=4&w=50&h=50&mask=circle)](https://github.com/mdjong1)[![113847439](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/113847439?v=4&w=50&h=50&mask=circle)](https://github.com/LunarMarathon)[![131469540](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/131469540?v=4&w=50&h=50&mask=circle)](https://github.com/knordstrom-muon)[![488594](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/488594?v=4&w=50&h=50&mask=circle)](https://github.com/jcugat)[![6984748](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6984748?v=4&w=50&h=50&mask=circle)](https://github.com/jbrambleDC)[![28351896](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/28351896?v=4&w=50&h=50&mask=circle)](https://github.com/JasonZhu1313)[![1274471](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1274471?v=4&w=50&h=50&mask=circle)](https://github.com/Sovietaced)[![7358951](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7358951?v=4&w=50&h=50&mask=circle)](https://github.com/frsann)[![121866694](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/121866694?v=4&w=50&h=50&mask=circle)](https://github.com/franco-bocci)[![1530049](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1530049?v=4&w=50&h=50&mask=circle)](https://github.com/felixmulder)[![111539728](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/111539728?v=4&w=50&h=50&mask=circle)](https://github.com/ddl-ebrown)[![23107192](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23107192?v=4&w=50&h=50&mask=circle)](https://github.com/YmirKhang)[![6596957](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6596957?v=4&w=50&h=50&mask=circle)](https://github.com/elibixby)[![173942673](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/173942673?v=4&w=50&h=50&mask=circle)](https://github.com/dylanspag-lmco)[![103009868](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/103009868?v=4&w=50&h=50&mask=circle)](https://github.com/douenergy)[![6774758](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6774758?v=4&w=50&h=50&mask=circle)](https://github.com/ddhirajkumar)[![50860453](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/50860453?v=4&w=50&h=50&mask=circle)](https://github.com/charlie0220)[![6506810](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6506810?v=4&w=50&h=50&mask=circle)](https://github.com/stephen37)[![6610300](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6610300?v=4&w=50&h=50&mask=circle)](https://github.com/ursucarina)[![55718143](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/55718143?v=4&w=50&h=50&mask=circle)](https://github.com/anrusina)[![65977800](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/65977800?v=4&w=50&h=50&mask=circle)](https://github.com/service-github-lyft-semantic-release)[![84735036](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/84735036?v=4&w=50&h=50&mask=circle)](https://github.com/jsonporter)[![85753828](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/85753828?v=4&w=50&h=50&mask=circle)](https://github.com/govalt)[![105876962](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/105876962?v=4&w=50&h=50&mask=circle)](https://github.com/james-union)[![101579322](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/101579322?v=4&w=50&h=50&mask=circle)](https://github.com/olga-union)[![26953709](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26953709?v=4&w=50&h=50&mask=circle)](https://github.com/Pianist038801)[![25038146](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25038146?v=4&w=50&h=50&mask=circle)](https://github.com/eugenejahn)[![88684372](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/88684372?v=4&w=50&h=50&mask=circle)](https://github.com/4nalog)[![8129392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8129392?v=4&w=50&h=50&mask=circle)](https://github.com/FrankFlitton)[![99441958](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/99441958?v=4&w=50&h=50&mask=circle)](https://github.com/apTalya)[![59022542](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/59022542?v=4&w=50&h=50&mask=circle)](https://github.com/lyonlu13)[![72861891](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/72861891?v=4&w=50&h=50&mask=circle)](https://github.com/xwk1246)[![1902623](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1902623?v=4&w=50&h=50&mask=circle)](https://github.com/trutx)[![59891164](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/59891164?v=4&w=50&h=50&mask=circle)](https://github.com/K-Kumar-01)[![20668349](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20668349?v=4&w=50&h=50&mask=circle)](https://github.com/HiromuHota)[![58770001](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/58770001?v=4&w=50&h=50&mask=circle)](https://github.com/Professional0321)[![1388071](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1388071?v=4&w=50&h=50&mask=circle)](https://github.com/aviaviavi)[![18363301](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18363301?v=4&w=50&h=50&mask=circle)](https://github.com/jimbobby5)[![25695302](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25695302?v=4&w=50&h=50&mask=circle)](https://github.com/sisco0)[![6399428](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6399428?v=4&w=50&h=50&mask=circle)](https://github.com/live-wire)[![17351764](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17351764?v=4&w=50&h=50&mask=circle)](https://github.com/daniel-shuy)[![31982395](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31982395?v=4&w=50&h=50&mask=circle)](https://github.com/alexapdev)[![7515359](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7515359?v=4&w=50&h=50&mask=circle)](https://github.com/narape)[![7548823](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7548823?v=4&w=50&h=50&mask=circle)](https://github.com/manuelrombach)[![50679871](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/50679871?v=4&w=50&h=50&mask=circle)](https://github.com/lupasarin)[![25364490](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25364490?v=4&w=50&h=50&mask=circle)](https://github.com/haoyuez)[![3451399](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3451399?v=4&w=50&h=50&mask=circle)](https://github.com/skiptomyliu)[![66767992](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/66767992?v=4&w=50&h=50&mask=circle)](https://github.com/10sharmashivam)[![62209650](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/62209650?v=4&w=50&h=50&mask=circle)](https://github.com/3t8)[![82604841](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/82604841?v=4&w=50&h=50&mask=circle)](https://github.com/davidmirror-ops)[![1892175](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1892175?v=4&w=50&h=50&mask=circle)](https://github.com/zeryx)[![66259759](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/66259759?v=4&w=50&h=50&mask=circle)](https://github.com/popojk)[![64233065](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/64233065?v=4&w=50&h=50&mask=circle)](https://github.com/rachfop)[![11166516](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11166516?v=4&w=50&h=50&mask=circle)](https://github.com/hebiao064)[![110307215](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/110307215?v=4&w=50&h=50&mask=circle)](https://github.com/sumana-2705)[![35962310](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/35962310?v=4&w=50&h=50&mask=circle)](https://github.com/trishitapingolia)[![91927689](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/91927689?v=4&w=50&h=50&mask=circle)](https://github.com/Smartmind12)[![726061](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/726061?v=4&w=50&h=50&mask=circle)](https://github.com/huxuan)[![42114946](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/42114946?v=4&w=50&h=50&mask=circle)](https://github.com/DenChenn)[![47872044](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/47872044?v=4&w=50&h=50&mask=circle)](https://github.com/privatedumbo)[![105229971](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/105229971?v=4&w=50&h=50&mask=circle)](https://github.com/tjKairos)[![200401](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/200401?v=4&w=50&h=50&mask=circle)](https://github.com/arturdryomov)[![13770222](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13770222?v=4&w=50&h=50&mask=circle)](https://github.com/ChickenTarm)[![117322020](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/117322020?v=4&w=50&h=50&mask=circle)](https://github.com/cdreetz)[![24739949](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24739949?v=4&w=50&h=50&mask=circle)](https://github.com/felixwang9817)[![64864908](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/64864908?v=4&w=50&h=50&mask=circle)](https://github.com/xshen8888)[![10430635](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10430635?v=4&w=50&h=50&mask=circle)](https://github.com/juandiegopalomino)[![31911175](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31911175?v=4&w=50&h=50&mask=circle)](https://github.com/kanyesthaker)[![104152793](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/104152793?v=4&w=50&h=50&mask=circle)](https://github.com/marc-union)[![27818609](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27818609?v=4&w=50&h=50&mask=circle)](https://github.com/michaeltinsley)[![22797900](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22797900?v=4&w=50&h=50&mask=circle)](https://github.com/stolarczyk)[![6486584](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6486584?v=4&w=50&h=50&mask=circle)](https://github.com/mucahitkantepe)[![321459](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/321459?v=4&w=50&h=50&mask=circle)](https://github.com/oyevtushok)[![405480](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/405480?v=4&w=50&h=50&mask=circle)](https://github.com/georgesnelling)[![54046807](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54046807?v=4&w=50&h=50&mask=circle)](https://github.com/kamaleybov)[![1004789](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1004789?v=4&w=50&h=50&mask=circle)](https://github.com/dschaller)[![1659415](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1659415?v=4&w=50&h=50&mask=circle)](https://github.com/dav009)[![1031759](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1031759?v=4&w=50&h=50&mask=circle)](https://github.com/agiron123)[![107633597](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/107633597?v=4&w=50&h=50&mask=circle)](https://github.com/peterghaddad)[![50983601](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/50983601?v=4&w=50&h=50&mask=circle)](https://github.com/zychen5186)[![136724527](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/136724527?v=4&w=50&h=50&mask=circle)](https://github.com/Murdock9803)[![144381122](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/144381122?v=4&w=50&h=50&mask=circle)](https://github.com/vraiyaninv)[![24486999](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24486999?v=4&w=50&h=50&mask=circle)](https://github.com/suravshrestha)[![69161722](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/69161722?v=4&w=50&h=50&mask=circle)](https://github.com/noobkid2411)[![790725](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/790725?v=4&w=50&h=50&mask=circle)](https://github.com/rodrigobaron)[![43336767](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43336767?v=4&w=50&h=50&mask=circle)](https://github.com/yongchand)[![36594527](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36594527?v=4&w=50&h=50&mask=circle)](https://github.com/mishmanners)[![25391173](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25391173?v=4&w=50&h=50&mask=circle)](https://github.com/nicklofaso)[![86911142](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/86911142?v=4&w=50&h=50&mask=circle)](https://github.com/idivyanshbansal)[![380927](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/380927?v=4&w=50&h=50&mask=circle)](https://github.com/cpaulik)[![480621](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/480621?v=4&w=50&h=50&mask=circle)](https://github.com/davidxia)[![1335881](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1335881?v=4&w=50&h=50&mask=circle)](https://github.com/hoyajigi)[![100597998](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/100597998?v=4&w=50&h=50&mask=circle)](https://github.com/MrKrishnaAgarwal)[![4830700](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4830700?v=4&w=50&h=50&mask=circle)](https://github.com/NitinAgg)[![139771199](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/139771199?v=4&w=50&h=50&mask=circle)](https://github.com/taieeuu)[![33272587](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/33272587?v=4&w=50&h=50&mask=circle)](https://github.com/samuel-sujith)[![10438373](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10438373?v=4&w=50&h=50&mask=circle)](https://github.com/SKalt)[![24543401](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24543401?v=4&w=50&h=50&mask=circle)](https://github.com/asoundarya96)[![141538510](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/141538510?v=4&w=50&h=50&mask=circle)](https://github.com/SophieTech88)[![47355538](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/47355538?v=4&w=50&h=50&mask=circle)](https://github.com/siiddhantt)[![54034701](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54034701?v=4&w=50&h=50&mask=circle)](https://github.com/peterxcli)[![580328](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/580328?v=4&w=50&h=50&mask=circle)](https://github.com/ilikedata)[![26265392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26265392?v=4&w=50&h=50&mask=circle)](https://github.com/ttanay)[![7144772](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7144772?v=4&w=50&h=50&mask=circle)](https://github.com/sighingnow)[![61864060](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/61864060?v=4&w=50&h=50&mask=circle)](https://github.com/HuangTing-Yao)[![1027207](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1027207?v=4&w=50&h=50&mask=circle)](https://github.com/orf)[![78115767](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/78115767?v=4&w=50&h=50&mask=circle)](https://github.com/trevormcguire)[![8755869](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8755869?v=4&w=50&h=50&mask=circle)](https://github.com/paravatha)[![141313113](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/141313113?v=4&w=50&h=50&mask=circle)](https://github.com/robert-ulbrich-mercedes-benz)[![6528449](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6528449?v=4&w=50&h=50&mask=circle)](https://github.com/uschi2000)[![576968](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/576968?v=4&w=50&h=50&mask=circle)](https://github.com/ronaldosaheki)[![10095462](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10095462?v=4&w=50&h=50&mask=circle)](https://github.com/GRomR1)[![144255851](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/144255851?v=4&w=50&h=50&mask=circle)](https://github.com/Sennuno)[![36827492](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36827492?v=4&w=50&h=50&mask=circle)](https://github.com/shahwar9)[![34468461](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/34468461?v=4&w=50&h=50&mask=circle)](https://github.com/sshardool)[![1908193](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1908193?v=4&w=50&h=50&mask=circle)](https://github.com/shengyu7697)[![133936](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/133936?v=4&w=50&h=50&mask=circle)](https://github.com/shihgianlee)[![119912892](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/119912892?v=4&w=50&h=50&mask=circle)](https://github.com/Virtual4087)[![46835608](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46835608?v=4&w=50&h=50&mask=circle)](https://github.com/shreyas44)[![40143026](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/40143026?v=4&w=50&h=50&mask=circle)](https://github.com/hampusrosvall)[![77197126](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/77197126?v=4&w=50&h=50&mask=circle)](https://github.com/hitarth01)[![300315](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/300315?v=4&w=50&h=50&mask=circle)](https://github.com/jcourteau)[![1220444](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1220444?v=4&w=50&h=50&mask=circle)](https://github.com/jkhales)[![106815366](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/106815366?v=4&w=50&h=50&mask=circle)](https://github.com/jw0515)[![1568889](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1568889?v=4&w=50&h=50&mask=circle)](https://github.com/leorleor)[![168411899](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/168411899?v=4&w=50&h=50&mask=circle)](https://github.com/mthemis-provenir)[![937967](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/937967?v=4&w=50&h=50&mask=circle)](https://github.com/moose007)[![73983677](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/73983677?v=4&w=50&h=50&mask=circle)](https://github.com/omahs)[![114232404](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/114232404?v=4&w=50&h=50&mask=circle)](https://github.com/sanjaychouhan-adf)[![11962777](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11962777?v=4&w=50&h=50&mask=circle)](https://github.com/ssen85)[![14996868](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14996868?v=4&w=50&h=50&mask=circle)](https://github.com/v01dXYZ)[![93438190](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/93438190?v=4&w=50&h=50&mask=circle)](https://github.com/wanderer163)[![16526627](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16526627?v=4&w=50&h=50&mask=circle)](https://github.com/vijaysaravana)[![697033](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/697033?v=4&w=50&h=50&mask=circle)](https://github.com/vglocus)[![2272137](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2272137?v=4&w=50&h=50&mask=circle)](https://github.com/Dlougach)[![39889](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/39889?v=4&w=50&h=50&mask=circle)](https://github.com/yarikoptic)[![12821510](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12821510?v=4&w=50&h=50&mask=circle)](https://github.com/ongkong)[![26526132](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26526132?v=4&w=50&h=50&mask=circle)](https://github.com/bearomorphism)[![43691987](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43691987?v=4&w=50&h=50&mask=circle)](https://github.com/desihsu)[![5346764](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5346764?v=4&w=50&h=50&mask=circle)](https://github.com/fsz285)[![143190185](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/143190185?v=4&w=50&h=50&mask=circle)](https://github.com/gdabisias)[![22917741](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22917741?v=4&w=50&h=50&mask=circle)](https://github.com/gigi-at-zymergen)[![11796986](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11796986?v=4&w=50&h=50&mask=circle)](https://github.com/avan-sh)[![489331](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/489331?v=4&w=50&h=50&mask=circle)](https://github.com/brndnblck)[![304786](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/304786?v=4&w=50&h=50&mask=circle)](https://github.com/kinow)[![156356273](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/156356273?v=4&w=50&h=50&mask=circle)](https://github.com/cratiu222)[![24402505](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24402505?v=4&w=50&h=50&mask=circle)](https://github.com/Daeruin)[![102558755](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/102558755?v=4&w=50&h=50&mask=circle)](https://github.com/dyu-bot)[![146735585](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/146735585?v=4&w=50&h=50&mask=circle)](https://github.com/nnsW3)[![20135478](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20135478?v=4&w=50&h=50&mask=circle)](https://github.com/Juneezee)[![1627021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1627021?v=4&w=50&h=50&mask=circle)](https://github.com/EraYaN)[![11456773](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11456773?v=4&w=50&h=50&mask=circle)](https://github.com/fvde)[![64676594](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/64676594?v=4&w=50&h=50&mask=circle)](https://github.com/abhijeet007rocks8)[![132337675](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/132337675?v=4&w=50&h=50&mask=circle)](https://github.com/adarsh-jha-dev)[![1627770](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1627770?v=4&w=50&h=50&mask=circle)](https://github.com/amitani)[![128223364](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/128223364?v=4&w=50&h=50&mask=circle)](https://github.com/blindaks)[![66388192](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/66388192?v=4&w=50&h=50&mask=circle)](https://github.com/mounesi)[![13237080](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13237080?v=4&w=50&h=50&mask=circle)](https://github.com/aminmaghsodi)[![14992189](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14992189?v=4&w=50&h=50&mask=circle)](https://github.com/eanakhl)[![1175392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1175392?v=4&w=50&h=50&mask=circle)](https://github.com/adinin)[![26172355](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26172355?v=4&w=50&h=50&mask=circle)](https://github.com/ALMerrill)[![48056316](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48056316?v=4&w=50&h=50&mask=circle)](https://github.com/ap0calypse8)[![7475946](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7475946?v=4&w=50&h=50&mask=circle)](https://github.com/anton-malakhov)[![1174730](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1174730?v=4&w=50&h=50&mask=circle)](https://github.com/mouuff)[![93093775](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/93093775?v=4&w=50&h=50&mask=circle)](https://github.com/Ash0807)[![44368997](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/44368997?v=4&w=50&h=50&mask=circle)](https://github.com/radiantly)[![16404204](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16404204?v=4&w=50&h=50&mask=circle)](https://github.com/Jeinhaus)[![3033592](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3033592?v=4&w=50&h=50&mask=circle)](https://github.com/kazesberger)[![13591898](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13591898?v=4&w=50&h=50&mask=circle)](https://github.com/lauralindy)[![19229049](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19229049?v=4&w=50&h=50&mask=circle)](https://github.com/lsena)[![123787712](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/123787712?v=4&w=50&h=50&mask=circle)](https://github.com/mark-thm)[![2236795](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2236795?v=4&w=50&h=50&mask=circle)](https://github.com/mhotan)[![10829864](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10829864?v=4&w=50&h=50&mask=circle)](https://github.com/mcanueste)[![36989112](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36989112?v=4&w=50&h=50&mask=circle)](https://github.com/nishantwrp)[![260015](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/260015?v=4&w=50&h=50&mask=circle)](https://github.com/ossareh)[![6987428](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6987428?v=4&w=50&h=50&mask=circle)](https://github.com/guyarad)[![1596283](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1596283?v=4&w=50&h=50&mask=circle)](https://github.com/guy4261)[![7490199](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7490199?v=4&w=50&h=50&mask=circle)](https://github.com/Lundez)[![10345184](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10345184?v=4&w=50&h=50&mask=circle)](https://github.com/hasukmistry)[![91054457](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/91054457?v=4&w=50&h=50&mask=circle)](https://github.com/HeetVekariya)[![29532638](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/29532638?v=4&w=50&h=50&mask=circle)](https://github.com/rokrokss)[![22633385](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22633385?v=4&w=50&h=50&mask=circle)](https://github.com/eltociear)[![151841](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/151841?v=4&w=50&h=50&mask=circle)](https://github.com/goodgravy)[![46633758](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46633758?v=4&w=50&h=50&mask=circle)](https://github.com/jsong336)[![14008978](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14008978?v=4&w=50&h=50&mask=circle)](https://github.com/jeremydonahue)[![9272376](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9272376?v=4&w=50&h=50&mask=circle)](https://github.com/jonasdebeukelaer)[![1633460](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1633460?v=4&w=50&h=50&mask=circle)](https://github.com/jmcarp)[![1043051](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1043051?v=4&w=50&h=50&mask=circle)](https://github.com/kylewaynebenson)[![21953442](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/21953442?v=4&w=50&h=50&mask=circle)](https://github.com/Gui11aum3)[![16461847](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16461847?v=4&w=50&h=50&mask=circle)](https://github.com/JakeNeyer)[![299421](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/299421?v=4&w=50&h=50&mask=circle)](https://github.com/aliavni)[![2845540](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2845540?v=4&w=50&h=50&mask=circle)](https://github.com/RustedBones)[![4056828](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4056828?v=4&w=50&h=50&mask=circle)](https://github.com/pablocasares)[![138898](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/138898?v=4&w=50&h=50&mask=circle)](https://github.com/andyczerwonka)[![150935185](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/150935185?v=4&w=50&h=50&mask=circle)](https://github.com/jschuchart-spot)[![471021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/471021?v=4&w=50&h=50&mask=circle)](https://github.com/marschall)[![5732047](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5732047?v=4&w=50&h=50&mask=circle)](https://github.com/stormy-ua)[![1071153](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1071153?v=4&w=50&h=50&mask=circle)](https://github.com/evdokim)[![13670774](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13670774?v=4&w=50&h=50&mask=circle)](https://github.com/AndersonReyes)[![438217](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/438217?v=4&w=50&h=50&mask=circle)](https://github.com/acet)[![71284190](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/71284190?v=4&w=50&h=50&mask=circle)](https://github.com/gdungca-fn)[![85021780](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/85021780?v=4&w=50&h=50&mask=circle)](https://github.com/Abdullahi-Ahmed)[![48512530](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48512530?v=4&w=50&h=50&mask=circle)](https://github.com/amaleelhamri)[![3275593](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3275593?v=4&w=50&h=50&mask=circle)](https://github.com/pradyunsg)[![66853113](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/68672?v=4&w=50&h=50&mask=circle)](https://github.com/apps/pre-commit-ci)[![1834509](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1834509?v=4&w=50&h=50&mask=circle)](https://github.com/jdknight)[![107893](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/107893?v=4&w=50&h=50&mask=circle)](https://github.com/kmike)[![1324225](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1324225?v=4&w=50&h=50&mask=circle)](https://github.com/hugovk)[![1300022](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1300022?v=4&w=50&h=50&mask=circle)](https://github.com/sirosen)[![244656](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/244656?v=4&w=50&h=50&mask=circle)](https://github.com/humitos)[![467294](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/467294?v=4&w=50&h=50&mask=circle)](https://github.com/bastimeyer)[![71486](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/71486?v=4&w=50&h=50&mask=circle)](https://github.com/asmeurer)[![20280470](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20280470?v=4&w=50&h=50&mask=circle)](https://github.com/drewyh)[![3533182](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3533182?v=4&w=50&h=50&mask=circle)](https://github.com/polyzen)[![199429](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/199429?v=4&w=50&h=50&mask=circle)](https://github.com/dvarrazzo)[![1032633](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1032633?v=4&w=50&h=50&mask=circle)](https://github.com/dbitouze)[![1313087](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1313087?v=4&w=50&h=50&mask=circle)](https://github.com/idryzhov)[![521097](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/521097?v=4&w=50&h=50&mask=circle)](https://github.com/pauloxnet)[![63936253](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/63936253?v=4&w=50&h=50&mask=circle)](https://github.com/ichard26)[![18519037](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18519037?v=4&w=50&h=50&mask=circle)](https://github.com/sethmlarson)[![413772](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/413772?v=4&w=50&h=50&mask=circle)](https://github.com/graingert)[![11478411](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11478411?v=4&w=50&h=50&mask=circle)](https://github.com/stonecharioteer)[![6739793](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6739793?v=4&w=50&h=50&mask=circle)](https://github.com/yeraydiazdiaz)[![83365562](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/83365562?v=4&w=50&h=50&mask=circle)](https://github.com/eviau-sat)[![6670894](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6670894?v=4&w=50&h=50&mask=circle)](https://github.com/rozsasarpi)[![86675](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/86675?v=4&w=50&h=50&mask=circle)](https://github.com/estan)[![4748863](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4748863?v=4&w=50&h=50&mask=circle)](https://github.com/pseudomuto)[![181308](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/181308?v=4&w=50&h=50&mask=circle)](https://github.com/htdvisser)[![1390277](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1390277?v=4&w=50&h=50&mask=circle)](https://github.com/jacobtolar)[![1391982](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1391982?v=4&w=50&h=50&mask=circle)](https://github.com/ezimanyi)[![135130171](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/135130171?v=4&w=50&h=50&mask=circle)](https://github.com/hmacias-avaya)[![3880001](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3880001?v=4&w=50&h=50&mask=circle)](https://github.com/lpabon)[![770392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/770392?v=4&w=50&h=50&mask=circle)](https://github.com/ArcEye)[![6178510](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6178510?v=4&w=50&h=50&mask=circle)](https://github.com/mingrammer)[![5111931](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5111931?v=4&w=50&h=50&mask=circle)](https://github.com/aschrijver)[![148219809](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/148219809?v=4&w=50&h=50&mask=circle)](https://github.com/panzerfahrer)[![16724](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16724?v=4&w=50&h=50&mask=circle)](https://github.com/glasser)[![17330872](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17330872?v=4&w=50&h=50&mask=circle)](https://github.com/murph0)[![419419](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/419419?v=4&w=50&h=50&mask=circle)](https://github.com/zetaron)[![1014](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1014?v=4&w=50&h=50&mask=circle)](https://github.com/sunfmin)[![504507](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/504507?v=4&w=50&h=50&mask=circle)](https://github.com/guozheng)[![8841470](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8841470?v=4&w=50&h=50&mask=circle)](https://github.com/suusan2go)[![901479](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/901479?v=4&w=50&h=50&mask=circle)](https://github.com/mhaberler)[![353644](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/353644?v=4&w=50&h=50&mask=circle)](https://github.com/dreampuf)[![12421077](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12421077?v=4&w=50&h=50&mask=circle)](https://github.com/UnicodingUnicorn)[![809865](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/809865?v=4&w=50&h=50&mask=circle)](https://github.com/philiptzou)[![19378](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19378?v=4&w=50&h=50&mask=circle)](https://github.com/timabell)[![614934](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/614934?v=4&w=50&h=50&mask=circle)](https://github.com/adzenith)[![1113245](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1113245?v=4&w=50&h=50&mask=circle)](https://github.com/jasonhancock)[![101659](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/101659?v=4&w=50&h=50&mask=circle)](https://github.com/matryer)[![4730508](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4730508?v=4&w=50&h=50&mask=circle)](https://github.com/piotrrojek)[![33036160](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/33036160?v=4&w=50&h=50&mask=circle)](https://github.com/jasonsattler)[![470810](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/470810?v=4&w=50&h=50&mask=circle)](https://github.com/sbward)[![7592392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7592392?v=4&w=50&h=50&mask=circle)](https://github.com/Pisush)[![94814](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/94814?v=4&w=50&h=50&mask=circle)](https://github.com/tamalsaha)[![8147854](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8147854?v=4&w=50&h=50&mask=circle)](https://github.com/marianina8)[![1683714](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1683714?v=4&w=50&h=50&mask=circle)](https://github.com/naysayer)[![2807589](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2807589?v=4&w=50&h=50&mask=circle)](https://github.com/darwayne)[![17263167](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17263167?v=4&w=50&h=50&mask=circle)](https://github.com/jsteenb2)[![1005](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1005?v=4&w=50&h=50&mask=circle)](https://github.com/ernesto-jimenez)[![6386887](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6386887?v=4&w=50&h=50&mask=circle)](https://github.com/AgrimPrasad)[![615811](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/615811?v=4&w=50&h=50&mask=circle)](https://github.com/dahernan)[![75184](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/75184?v=4&w=50&h=50&mask=circle)](https://github.com/jtarchie)[![469669](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/469669?v=4&w=50&h=50&mask=circle)](https://github.com/jdtobe)[![28523](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/28523?v=4&w=50&h=50&mask=circle)](https://github.com/alrs)[![426880](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/426880?v=4&w=50&h=50&mask=circle)](https://github.com/tkent)[![10113228](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10113228?v=4&w=50&h=50&mask=circle)](https://github.com/urisimchoni)[![5751464](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5751464?v=4&w=50&h=50&mask=circle)](https://github.com/Xercoy)[![2405410](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2405410?v=4&w=50&h=50&mask=circle)](https://github.com/marbergq)[![5082160](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5082160?v=4&w=50&h=50&mask=circle)](https://github.com/anothrNick)[![11335612](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11335612?v=4&w=50&h=50&mask=circle)](https://github.com/fermoya)[![23391642](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23391642?v=4&w=50&h=50&mask=circle)](https://github.com/sbe-arg)[![1024762](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1024762?v=4&w=50&h=50&mask=circle)](https://github.com/PeerXu)[![7390781](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7390781?v=4&w=50&h=50&mask=circle)](https://github.com/reececomo)[![49680](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49680?v=4&w=50&h=50&mask=circle)](https://github.com/dmerrick)[![87524](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/87524?v=4&w=50&h=50&mask=circle)](https://github.com/andrewcole)[![866505](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/866505?v=4&w=50&h=50&mask=circle)](https://github.com/phish108)[![2611549](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2611549?v=4&w=50&h=50&mask=circle)](https://github.com/endrjuskr)[![8232503](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8232503?v=4&w=50&h=50&mask=circle)](https://github.com/sjauld)[![118945041](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/118945041?v=4&w=50&h=50&mask=circle)](https://github.com/vq-ambiata)[![3807434](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3807434?v=4&w=50&h=50&mask=circle)](https://github.com/tomsolem)[![16513382](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16513382?v=4&w=50&h=50&mask=circle)](https://github.com/117)[![8320753](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8320753?v=4&w=50&h=50&mask=circle)](https://github.com/lovromazgon)[![5655837](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5655837?v=4&w=50&h=50&mask=circle)](https://github.com/gukoff)[![49961058](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49961058?v=4&w=50&h=50&mask=circle)](https://github.com/bevans-HD)[![25625597](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25625597?v=4&w=50&h=50&mask=circle)](https://github.com/zero-below)[![62775347](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/62775347?v=4&w=50&h=50&mask=circle)](https://github.com/okozachenko1203)[![53085803](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/53085803?v=4&w=50&h=50&mask=circle)](https://github.com/cuttingedge1109)[![5067549](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5067549?v=4&w=50&h=50&mask=circle)](https://github.com/pellared)[![25486791](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25486791?v=4&w=50&h=50&mask=circle)](https://github.com/pavyarov)[![995707](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/995707?v=4&w=50&h=50&mask=circle)](https://github.com/OskarStark)[![2302957](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2302957?v=4&w=50&h=50&mask=circle)](https://github.com/JeremyLWright)[![10090384](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10090384?v=4&w=50&h=50&mask=circle)](https://github.com/ivanpk)[![17337515](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17337515?v=4&w=50&h=50&mask=circle)](https://github.com/fabricepipart)[![8296645](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8296645?v=4&w=50&h=50&mask=circle)](https://github.com/imdanielsp)[![6388483](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6388483?v=4&w=50&h=50&mask=circle)](https://github.com/zsedem)[![69170839](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/69170839?v=4&w=50&h=50&mask=circle)](https://github.com/adam-berrio)[![282792](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/282792?v=4&w=50&h=50&mask=circle)](https://github.com/asford)[![38894122](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/38894122?v=4&w=50&h=50&mask=circle)](https://github.com/bmcconeghy)[![16698198](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16698198?v=4&w=50&h=50&mask=circle)](https://github.com/conda-forge-admin)[![36490558](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36490558?v=4&w=50&h=50&mask=circle)](https://github.com/regro-cf-autotick-bot)[![79913779](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/102928?v=4&w=50&h=50&mask=circle)](https://github.com/apps/conda-forge-curator)[![41898282](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/15368?v=4&w=50&h=50&mask=circle)](https://github.com/apps/github-actions)[![18567580](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18567580?v=4&w=50&h=50&mask=circle)](https://github.com/conda-forge-linter)[![72671586](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/72671586?v=4&w=50&h=50&mask=circle)](https://github.com/pheianox)[![3760025](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3760025?v=4&w=50&h=50&mask=circle)](https://github.com/gaga5lala)[![115705553](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/115705553?v=4&w=50&h=50&mask=circle)](https://github.com/divyank000) +[![953358](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/953358?v=4&w=50&h=50&mask=circle)](https://github.com/katrogan)[![37090125](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37090125?v=4&w=50&h=50&mask=circle)](https://github.com/lyft-metaservice-3)[![7597118](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7597118?v=4&w=50&h=50&mask=circle)](https://github.com/matthewphsmith)[![27159](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27159?v=4&w=50&h=50&mask=circle)](https://github.com/EngHabu)[![29843943](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/29843943?v=4&w=50&h=50&mask=circle)](https://github.com/goreleaserbot)[![8888115](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8888115?v=4&w=50&h=50&mask=circle)](https://github.com/hamersaw)[![10830562](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10830562?v=4&w=50&h=50&mask=circle)](https://github.com/yindia)[![78108056](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/78108056?v=4&w=50&h=50&mask=circle)](https://github.com/flyte-bot)[![158892](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/158892?v=4&w=50&h=50&mask=circle)](https://github.com/honnix)[![18408237](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18408237?v=4&w=50&h=50&mask=circle)](https://github.com/anandswaminathan)[![2896568](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2896568?v=4&w=50&h=50&mask=circle)](https://github.com/wild-endeavor)[![37936015](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37936015?v=4&w=50&h=50&mask=circle)](https://github.com/pingsutw)[![653394](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/653394?v=4&w=50&h=50&mask=circle)](https://github.com/eapolinario)[![1518524](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1518524?v=4&w=50&h=50&mask=circle)](https://github.com/bnsblue)[![27724763](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27724763?v=4&w=50&h=50&mask=circle)](https://github.com/iaroslav-ciupin)[![16888709](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16888709?v=4&w=50&h=50&mask=circle)](https://github.com/kumare3)[![27777173](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27777173?v=4&w=50&h=50&mask=circle)](https://github.com/samhita-alla)[![23062603](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23062603?v=4&w=50&h=50&mask=circle)](https://github.com/Antaxify)[![77798312](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/77798312?v=4&w=50&h=50&mask=circle)](https://github.com/pmahindrakar-oss)[![5032356](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5032356?v=4&w=50&h=50&mask=circle)](https://github.com/brucearctor)[![8805803](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8805803?v=4&w=50&h=50&mask=circle)](https://github.com/alexlipa91)[![6239450](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6239450?v=4&w=50&h=50&mask=circle)](https://github.com/mayitbeegh)[![452166](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/452166?v=4&w=50&h=50&mask=circle)](https://github.com/MorpheusXAUT)[![15335863](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/15335863?v=4&w=50&h=50&mask=circle)](https://github.com/gvashishtha)[![6562898](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6562898?v=4&w=50&h=50&mask=circle)](https://github.com/ckiosidis)[![4748985](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4748985?v=4&w=50&h=50&mask=circle)](https://github.com/aliabbasjaffri)[![76461262](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/76461262?v=4&w=50&h=50&mask=circle)](https://github.com/Future-Outlier)[![5725707](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5725707?v=4&w=50&h=50&mask=circle)](https://github.com/andrewwdye)[![8122852](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8122852?v=4&w=50&h=50&mask=circle)](https://github.com/ariefrahmansyah)[![10869815](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10869815?v=4&w=50&h=50&mask=circle)](https://github.com/jeevb)[![3880645](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3880645?v=4&w=50&h=50&mask=circle)](https://github.com/jonathanburns)[![3936213](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3936213?v=4&w=50&h=50&mask=circle)](https://github.com/lu4nm3)[![26174213](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26174213?v=4&w=50&h=50&mask=circle)](https://github.com/lyft-metaservice-2)[![126913098](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/126913098?v=4&w=50&h=50&mask=circle)](https://github.com/squiishyy)[![46989299](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46989299?v=4&w=50&h=50&mask=circle)](https://github.com/supreeth7)[![1815175](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1815175?v=4&w=50&h=50&mask=circle)](https://github.com/schottra)[![37558497](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37558497?v=4&w=50&h=50&mask=circle)](https://github.com/pvditt)[![5487021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5487021?v=4&w=50&h=50&mask=circle)](https://github.com/veggiemonk)[![9142716](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9142716?v=4&w=50&h=50&mask=circle)](https://github.com/2uasimojo)[![2816689](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2816689?v=4&w=50&h=50&mask=circle)](https://github.com/cosmicBboy)[![19375241](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19375241?v=4&w=50&h=50&mask=circle)](https://github.com/migueltol22)[![24364830](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24364830?v=4&w=50&h=50&mask=circle)](https://github.com/ByronHsu)[![53313394](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/53313394?v=4&w=50&h=50&mask=circle)](https://github.com/kosigz-lyft)[![43610471](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43610471?v=4&w=50&h=50&mask=circle)](https://github.com/yk-x-25)[![10526540](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10526540?v=4&w=50&h=50&mask=circle)](https://github.com/yubofredwang)[![16090976](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16090976?v=4&w=50&h=50&mask=circle)](https://github.com/surindersinghp)[![94349093](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/94349093?v=4&w=50&h=50&mask=circle)](https://github.com/SmritiSatyanV)[![70988](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/70988?v=4&w=50&h=50&mask=circle)](https://github.com/slai)[![6065051](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6065051?v=4&w=50&h=50&mask=circle)](https://github.com/milton0825)[![38207208](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/38207208?v=4&w=50&h=50&mask=circle)](https://github.com/tnsetting)[![95110820](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/95110820?v=4&w=50&h=50&mask=circle)](https://github.com/jerempy)[![11799671](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11799671?v=4&w=50&h=50&mask=circle)](https://github.com/bstadlbauer)[![34587798](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/34587798?v=4&w=50&h=50&mask=circle)](https://github.com/akhurana001)[![5026554](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5026554?v=4&w=50&h=50&mask=circle)](https://github.com/vsbus)[![1472826](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1472826?v=4&w=50&h=50&mask=circle)](https://github.com/maximsmol)[![31255434](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31255434?v=4&w=50&h=50&mask=circle)](https://github.com/kennyworkman)[![1330233](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1330233?v=4&w=50&h=50&mask=circle)](https://github.com/igorvalko)[![248688](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/248688?v=4&w=50&h=50&mask=circle)](https://github.com/hanzo)[![467927](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/467927?v=4&w=50&h=50&mask=circle)](https://github.com/kanterov)[![36511035](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36511035?v=4&w=50&h=50&mask=circle)](https://github.com/fg91)[![4967458](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4967458?v=4&w=50&h=50&mask=circle)](https://github.com/chanadian)[![8200209](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8200209?v=4&w=50&h=50&mask=circle)](https://github.com/catalinii)[![43587819](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43587819?v=4&w=50&h=50&mask=circle)](https://github.com/chetcode)[![163899](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/163899?v=4&w=50&h=50&mask=circle)](https://github.com/regadas)[![54248170](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54248170?v=4&w=50&h=50&mask=circle)](https://github.com/nicholasjng)[![2538760](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2538760?v=4&w=50&h=50&mask=circle)](https://github.com/akumor)[![104257](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/104257?v=4&w=50&h=50&mask=circle)](https://github.com/flixr)[![92917168](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/92917168?v=4&w=50&h=50&mask=circle)](https://github.com/edwinyyyu)[![1360529](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1360529?v=4&w=50&h=50&mask=circle)](https://github.com/clairemcginty)[![1777447](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1777447?v=4&w=50&h=50&mask=circle)](https://github.com/goyalankit)[![1316881](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1316881?v=4&w=50&h=50&mask=circle)](https://github.com/akashkatipally)[![22784654](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22784654?v=4&w=50&h=50&mask=circle)](https://github.com/aybidi)[![5402633](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5402633?v=4&w=50&h=50&mask=circle)](https://github.com/thomasjpfan)[![49699333](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/29110?v=4&w=50&h=50&mask=circle)](https://github.com/apps/dependabot)[![72752478](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/72752478?v=4&w=50&h=50&mask=circle)](https://github.com/Mecoli1219)[![19733683](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19733683?v=4&w=50&h=50&mask=circle)](https://github.com/snyk-bot)[![114708546](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/114708546?v=4&w=50&h=50&mask=circle)](https://github.com/troychiu)[![35886692](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/35886692?v=4&w=50&h=50&mask=circle)](https://github.com/austin362667)[![62143443](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/62143443?v=4&w=50&h=50&mask=circle)](https://github.com/mao3267)[![9131935](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9131935?v=4&w=50&h=50&mask=circle)](https://github.com/Tom-Newton)[![47914085](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/47914085?v=4&w=50&h=50&mask=circle)](https://github.com/MortalHappiness)[![155087](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/155087?v=4&w=50&h=50&mask=circle)](https://github.com/derwiki)[![40698988](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/40698988?v=4&w=50&h=50&mask=circle)](https://github.com/dansola)[![14800485](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14800485?v=4&w=50&h=50&mask=circle)](https://github.com/jasonlai1218)[![31577879](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31577879?v=4&w=50&h=50&mask=circle)](https://github.com/pryce-turner)[![1399455](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1399455?v=4&w=50&h=50&mask=circle)](https://github.com/th0114nd)[![36886416](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36886416?v=4&w=50&h=50&mask=circle)](https://github.com/JiangJiaWei1103)[![58504997](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/58504997?v=4&w=50&h=50&mask=circle)](https://github.com/novahow)[![89976021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/89976021?v=4&w=50&h=50&mask=circle)](https://github.com/fiedlerNr9)[![46030368](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46030368?v=4&w=50&h=50&mask=circle)](https://github.com/ChungYujoyce)[![21109744](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/21109744?v=4&w=50&h=50&mask=circle)](https://github.com/AlekhyaSasi)[![1153481](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1153481?v=4&w=50&h=50&mask=circle)](https://github.com/ppiegaze)[![1810591](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1810591?v=4&w=50&h=50&mask=circle)](https://github.com/asottile)[![54340816](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54340816?v=4&w=50&h=50&mask=circle)](https://github.com/granthamtaylor)[![51814063](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/51814063?v=4&w=50&h=50&mask=circle)](https://github.com/Yicheng-Lu-llll)[![9609986](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9609986?v=4&w=50&h=50&mask=circle)](https://github.com/sonjaer)[![35151789](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/35151789?v=4&w=50&h=50&mask=circle)](https://github.com/ggydush)[![140021987](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/140021987?v=4&w=50&h=50&mask=circle)](https://github.com/ddl-rliu)[![138256885](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/138256885?v=4&w=50&h=50&mask=circle)](https://github.com/ysysys3074)[![3939659](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3939659?v=4&w=50&h=50&mask=circle)](https://github.com/sbrunk)[![80421934](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/80421934?v=4&w=50&h=50&mask=circle)](https://github.com/SandraGH5)[![52046377](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/52046377?v=4&w=50&h=50&mask=circle)](https://github.com/hhcs9527)[![4406268](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4406268?v=4&w=50&h=50&mask=circle)](https://github.com/otarabai)[![16709018](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16709018?v=4&w=50&h=50&mask=circle)](https://github.com/noahjax)[![417209](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/417209?v=4&w=50&h=50&mask=circle)](https://github.com/neverett)[![27844407](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27844407?v=4&w=50&h=50&mask=circle)](https://github.com/ringohoffman)[![106939297](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/106939297?v=4&w=50&h=50&mask=circle)](https://github.com/chaohengstudent)[![380854](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/380854?v=4&w=50&h=50&mask=circle)](https://github.com/bgedik)[![18337807](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18337807?v=4&w=50&h=50&mask=circle)](https://github.com/max-hoffman)[![1276867](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1276867?v=4&w=50&h=50&mask=circle)](https://github.com/JackUrb)[![115421902](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/115421902?v=4&w=50&h=50&mask=circle)](https://github.com/wayner0628)[![169746411](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/169746411?v=4&w=50&h=50&mask=circle)](https://github.com/davidlin20dev)[![134093844](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/134093844?v=4&w=50&h=50&mask=circle)](https://github.com/rdeaton-freenome)[![106936600](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/106936600?v=4&w=50&h=50&mask=circle)](https://github.com/peridotml)[![26268253](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26268253?v=4&w=50&h=50&mask=circle)](https://github.com/arbaobao)[![16509490](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16509490?v=4&w=50&h=50&mask=circle)](https://github.com/ryankarlos)[![98242479](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/98242479?v=4&w=50&h=50&mask=circle)](https://github.com/RichhLi)[![98349643](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/98349643?v=4&w=50&h=50&mask=circle)](https://github.com/rahul-theorem)[![12219405](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12219405?v=4&w=50&h=50&mask=circle)](https://github.com/fediazgon)[![26092524](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26092524?v=4&w=50&h=50&mask=circle)](https://github.com/fellhorn)[![322624](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/322624?v=4&w=50&h=50&mask=circle)](https://github.com/AdrianoKF)[![17165004](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17165004?v=4&w=50&h=50&mask=circle)](https://github.com/RobertoRRW)[![30375389](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/30375389?v=4&w=50&h=50&mask=circle)](https://github.com/bimtauer)[![92072956](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/92072956?v=4&w=50&h=50&mask=circle)](https://github.com/PudgyPigeon)[![97543480](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/97543480?v=4&w=50&h=50&mask=circle)](https://github.com/esadler-hbo)[![69013027](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/69013027?v=4&w=50&h=50&mask=circle)](https://github.com/ggydush-fn)[![116700206](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/116700206?v=4&w=50&h=50&mask=circle)](https://github.com/kiliangojek)[![1521126](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1521126?v=4&w=50&h=50&mask=circle)](https://github.com/pbrogan12)[![120470035](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/120470035?v=4&w=50&h=50&mask=circle)](https://github.com/redartera)[![4025771](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4025771?v=4&w=50&h=50&mask=circle)](https://github.com/andresgomezfrr)[![422486](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/422486?v=4&w=50&h=50&mask=circle)](https://github.com/bethebunny)[![953385](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/953385?v=4&w=50&h=50&mask=circle)](https://github.com/blaketastic2)[![1168692](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1168692?v=4&w=50&h=50&mask=circle)](https://github.com/dennisobrien)[![173942673](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/173942673?v=4&w=50&h=50&mask=circle)](https://github.com/dylanspag-lmco)[![33652917](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/33652917?v=4&w=50&h=50&mask=circle)](https://github.com/hfurkanvural)[![45017130](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/45017130?v=4&w=50&h=50&mask=circle)](https://github.com/helenzhangyc)[![1274471](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1274471?v=4&w=50&h=50&mask=circle)](https://github.com/Sovietaced)[![91385411](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/91385411?v=4&w=50&h=50&mask=circle)](https://github.com/Ln11211)[![30621230](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/30621230?v=4&w=50&h=50&mask=circle)](https://github.com/aeioulisa)[![54334265](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54334265?v=4&w=50&h=50&mask=circle)](https://github.com/michaels-lyft)[![48736656](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48736656?v=4&w=50&h=50&mask=circle)](https://github.com/murilommen)[![150836163](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/150836163?v=4&w=50&h=50&mask=circle)](https://github.com/neilisaur)[![38955457](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/38955457?v=4&w=50&h=50&mask=circle)](https://github.com/RRK1000)[![2614101](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2614101?v=4&w=50&h=50&mask=circle)](https://github.com/RobinKa)[![4308533](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4308533?v=4&w=50&h=50&mask=circle)](https://github.com/rubenbarragan)[![10201242](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10201242?v=4&w=50&h=50&mask=circle)](https://github.com/sugatoray)[![11269256](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11269256?v=4&w=50&h=50&mask=circle)](https://github.com/sushrut111)[![139771199](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/139771199?v=4&w=50&h=50&mask=circle)](https://github.com/taieeuu)[![61228633](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/61228633?v=4&w=50&h=50&mask=circle)](https://github.com/Tat-V)[![13070236](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13070236?v=4&w=50&h=50&mask=circle)](https://github.com/TeoZosa)[![8817639](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8817639?v=4&w=50&h=50&mask=circle)](https://github.com/ThomVett)[![17309187](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17309187?v=4&w=50&h=50&mask=circle)](https://github.com/datability-io)[![81233629](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/81233629?v=4&w=50&h=50&mask=circle)](https://github.com/101rakibulhasan)[![97332401](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/97332401?v=4&w=50&h=50&mask=circle)](https://github.com/RaghavMangla)[![100569684](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/100569684?v=4&w=50&h=50&mask=circle)](https://github.com/RRap0so)[![147648834](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/147648834?v=4&w=50&h=50&mask=circle)](https://github.com/quinten-flwls)[![37170063](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37170063?v=4&w=50&h=50&mask=circle)](https://github.com/Qiwen-Yu)[![43886578](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43886578?v=4&w=50&h=50&mask=circle)](https://github.com/400Ping)[![125105](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/125105?v=4&w=50&h=50&mask=circle)](https://github.com/tekumara)[![37547264](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/37547264?v=4&w=50&h=50&mask=circle)](https://github.com/Nan2018)[![49385643](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49385643?v=4&w=50&h=50&mask=circle)](https://github.com/MinuraPunchihewa)[![2640499](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2640499?v=4&w=50&h=50&mask=circle)](https://github.com/wirthual)[![4417105](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4417105?v=4&w=50&h=50&mask=circle)](https://github.com/Terryhung)[![73247359](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/73247359?v=4&w=50&h=50&mask=circle)](https://github.com/stef-stripe)[![12913704](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12913704?v=4&w=50&h=50&mask=circle)](https://github.com/mg515)[![119345186](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/119345186?v=4&w=50&h=50&mask=circle)](https://github.com/mcloney-ddm)[![13331724](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13331724?v=4&w=50&h=50&mask=circle)](https://github.com/martinlyra)[![24611279](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24611279?v=4&w=50&h=50&mask=circle)](https://github.com/ericwudayi)[![6333870](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6333870?v=4&w=50&h=50&mask=circle)](https://github.com/demmerichs)[![4023015](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4023015?v=4&w=50&h=50&mask=circle)](https://github.com/pradithya)[![12450632](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12450632?v=4&w=50&h=50&mask=circle)](https://github.com/ajsalow)[![3741621](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3741621?v=4&w=50&h=50&mask=circle)](https://github.com/palchicz)[![43726198](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43726198?v=4&w=50&h=50&mask=circle)](https://github.com/yundai424)[![131146298](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/131146298?v=4&w=50&h=50&mask=circle)](https://github.com/yini7777)[![29053051](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/29053051?v=4&w=50&h=50&mask=circle)](https://github.com/XinEDprob)[![52355146](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/52355146?v=4&w=50&h=50&mask=circle)](https://github.com/lowc1012)[![40901950](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/40901950?v=4&w=50&h=50&mask=circle)](https://github.com/WebOfNakedFancies)[![67166843](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/67166843?v=4&w=50&h=50&mask=circle)](https://github.com/vvasavada-fn)[![15071835](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/15071835?v=4&w=50&h=50&mask=circle)](https://github.com/va6996)[![3391550](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3391550?v=4&w=50&h=50&mask=circle)](https://github.com/devictr)[![57967031](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/57967031?v=4&w=50&h=50&mask=circle)](https://github.com/varshaparthay)[![5092599](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5092599?v=4&w=50&h=50&mask=circle)](https://github.com/vchowdhary)[![26834658](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26834658?v=4&w=50&h=50&mask=circle)](https://github.com/techytushar)[![14007150](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14007150?v=4&w=50&h=50&mask=circle)](https://github.com/deepyaman)[![2380665](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2380665?v=4&w=50&h=50&mask=circle)](https://github.com/DavidMertz)[![16297104](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16297104?v=4&w=50&h=50&mask=circle)](https://github.com/danpf)[![10463690](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10463690?v=4&w=50&h=50&mask=circle)](https://github.com/cjidboon94)[![26920893](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26920893?v=4&w=50&h=50&mask=circle)](https://github.com/chinghongfang)[![27000005](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27000005?v=4&w=50&h=50&mask=circle)](https://github.com/supercharleszhu)[![420942](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/420942?v=4&w=50&h=50&mask=circle)](https://github.com/cameronraysmith)[![6288302](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6288302?v=4&w=50&h=50&mask=circle)](https://github.com/CalvinLeather)[![179035736](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/179035736?v=4&w=50&h=50&mask=circle)](https://github.com/bryan-hunted)[![4396228](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4396228?v=4&w=50&h=50&mask=circle)](https://github.com/bryanwweber)[![7422223](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7422223?v=4&w=50&h=50&mask=circle)](https://github.com/bcvanmeurs)[![234145](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/234145?v=4&w=50&h=50&mask=circle)](https://github.com/benoistlaurent)[![31381038](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31381038?v=4&w=50&h=50&mask=circle)](https://github.com/lordnodd)[![49250723](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49250723?v=4&w=50&h=50&mask=circle)](https://github.com/ArthurBook)[![58334441](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/58334441?v=4&w=50&h=50&mask=circle)](https://github.com/wckdman)[![23013825](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23013825?v=4&w=50&h=50&mask=circle)](https://github.com/arpitbhardwaj)[![77167782](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/77167782?v=4&w=50&h=50&mask=circle)](https://github.com/apatel-fn)[![48966647](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48966647?v=4&w=50&h=50&mask=circle)](https://github.com/asahalyft)[![7005765](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7005765?v=4&w=50&h=50&mask=circle)](https://github.com/convexquad)[![54333860](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54333860?v=4&w=50&h=50&mask=circle)](https://github.com/aalavian)[![110886184](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/110886184?v=4&w=50&h=50&mask=circle)](https://github.com/aditya7302)[![10376195](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10376195?v=4&w=50&h=50&mask=circle)](https://github.com/myz540)[![19853373](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19853373?v=4&w=50&h=50&mask=circle)](https://github.com/NotMatthewGriffin)[![34498039](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/34498039?v=4&w=50&h=50&mask=circle)](https://github.com/matheusMoreno)[![20173739](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20173739?v=4&w=50&h=50&mask=circle)](https://github.com/madhur-tandon)[![4410453](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4410453?v=4&w=50&h=50&mask=circle)](https://github.com/mdjong1)[![113847439](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/113847439?v=4&w=50&h=50&mask=circle)](https://github.com/LunarMarathon)[![131469540](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/131469540?v=4&w=50&h=50&mask=circle)](https://github.com/knordstrom-muon)[![488594](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/488594?v=4&w=50&h=50&mask=circle)](https://github.com/jcugat)[![6984748](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6984748?v=4&w=50&h=50&mask=circle)](https://github.com/jbrambleDC)[![28351896](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/28351896?v=4&w=50&h=50&mask=circle)](https://github.com/JasonZhu1313)[![7358951](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7358951?v=4&w=50&h=50&mask=circle)](https://github.com/frsann)[![121866694](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/121866694?v=4&w=50&h=50&mask=circle)](https://github.com/franco-bocci)[![1530049](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1530049?v=4&w=50&h=50&mask=circle)](https://github.com/felixmulder)[![111539728](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/111539728?v=4&w=50&h=50&mask=circle)](https://github.com/ddl-ebrown)[![23107192](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23107192?v=4&w=50&h=50&mask=circle)](https://github.com/YmirKhang)[![6596957](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6596957?v=4&w=50&h=50&mask=circle)](https://github.com/elibixby)[![103009868](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/103009868?v=4&w=50&h=50&mask=circle)](https://github.com/douenergy)[![6774758](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6774758?v=4&w=50&h=50&mask=circle)](https://github.com/ddhirajkumar)[![50860453](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/50860453?v=4&w=50&h=50&mask=circle)](https://github.com/charlie0220)[![6506810](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6506810?v=4&w=50&h=50&mask=circle)](https://github.com/stephen37)[![6610300](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6610300?v=4&w=50&h=50&mask=circle)](https://github.com/ursucarina)[![55718143](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/55718143?v=4&w=50&h=50&mask=circle)](https://github.com/anrusina)[![65977800](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/65977800?v=4&w=50&h=50&mask=circle)](https://github.com/service-github-lyft-semantic-release)[![84735036](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/84735036?v=4&w=50&h=50&mask=circle)](https://github.com/jsonporter)[![85753828](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/85753828?v=4&w=50&h=50&mask=circle)](https://github.com/govalt)[![105876962](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/105876962?v=4&w=50&h=50&mask=circle)](https://github.com/james-union)[![101579322](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/101579322?v=4&w=50&h=50&mask=circle)](https://github.com/olga-union)[![26953709](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26953709?v=4&w=50&h=50&mask=circle)](https://github.com/Pianist038801)[![25038146](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25038146?v=4&w=50&h=50&mask=circle)](https://github.com/eugenejahn)[![88684372](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/88684372?v=4&w=50&h=50&mask=circle)](https://github.com/4nalog)[![8129392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8129392?v=4&w=50&h=50&mask=circle)](https://github.com/FrankFlitton)[![99441958](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/99441958?v=4&w=50&h=50&mask=circle)](https://github.com/apTalya)[![59022542](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/59022542?v=4&w=50&h=50&mask=circle)](https://github.com/lyonlu13)[![72861891](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/72861891?v=4&w=50&h=50&mask=circle)](https://github.com/xwk1246)[![1902623](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1902623?v=4&w=50&h=50&mask=circle)](https://github.com/trutx)[![59891164](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/59891164?v=4&w=50&h=50&mask=circle)](https://github.com/K-Kumar-01)[![20668349](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20668349?v=4&w=50&h=50&mask=circle)](https://github.com/HiromuHota)[![58770001](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/58770001?v=4&w=50&h=50&mask=circle)](https://github.com/Professional0321)[![1388071](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1388071?v=4&w=50&h=50&mask=circle)](https://github.com/aviaviavi)[![18363301](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18363301?v=4&w=50&h=50&mask=circle)](https://github.com/jimbobby5)[![25695302](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25695302?v=4&w=50&h=50&mask=circle)](https://github.com/sisco0)[![6399428](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6399428?v=4&w=50&h=50&mask=circle)](https://github.com/live-wire)[![17351764](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17351764?v=4&w=50&h=50&mask=circle)](https://github.com/daniel-shuy)[![31982395](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31982395?v=4&w=50&h=50&mask=circle)](https://github.com/alexapdev)[![7515359](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7515359?v=4&w=50&h=50&mask=circle)](https://github.com/narape)[![7548823](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7548823?v=4&w=50&h=50&mask=circle)](https://github.com/manuelrombach)[![50679871](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/50679871?v=4&w=50&h=50&mask=circle)](https://github.com/lupasarin)[![25364490](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25364490?v=4&w=50&h=50&mask=circle)](https://github.com/haoyuez)[![3451399](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3451399?v=4&w=50&h=50&mask=circle)](https://github.com/skiptomyliu)[![66767992](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/66767992?v=4&w=50&h=50&mask=circle)](https://github.com/10sharmashivam)[![62209650](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/62209650?v=4&w=50&h=50&mask=circle)](https://github.com/3t8)[![82604841](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/82604841?v=4&w=50&h=50&mask=circle)](https://github.com/davidmirror-ops)[![1892175](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1892175?v=4&w=50&h=50&mask=circle)](https://github.com/zeryx)[![66259759](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/66259759?v=4&w=50&h=50&mask=circle)](https://github.com/popojk)[![64233065](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/64233065?v=4&w=50&h=50&mask=circle)](https://github.com/rachfop)[![53571625](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/53571625?v=4&w=50&h=50&mask=circle)](https://github.com/Soot3)[![11166516](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11166516?v=4&w=50&h=50&mask=circle)](https://github.com/hebiao064)[![110307215](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/110307215?v=4&w=50&h=50&mask=circle)](https://github.com/sumana-2705)[![35962310](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/35962310?v=4&w=50&h=50&mask=circle)](https://github.com/trishitapingolia)[![91927689](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/91927689?v=4&w=50&h=50&mask=circle)](https://github.com/Smartmind12)[![726061](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/726061?v=4&w=50&h=50&mask=circle)](https://github.com/huxuan)[![42114946](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/42114946?v=4&w=50&h=50&mask=circle)](https://github.com/DenChenn)[![60069744](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/60069744?v=4&w=50&h=50&mask=circle)](https://github.com/machichima)[![47872044](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/47872044?v=4&w=50&h=50&mask=circle)](https://github.com/privatedumbo)[![105229971](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/105229971?v=4&w=50&h=50&mask=circle)](https://github.com/tjKairos)[![200401](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/200401?v=4&w=50&h=50&mask=circle)](https://github.com/arturdryomov)[![13770222](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13770222?v=4&w=50&h=50&mask=circle)](https://github.com/ChickenTarm)[![117322020](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/117322020?v=4&w=50&h=50&mask=circle)](https://github.com/cdreetz)[![24739949](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24739949?v=4&w=50&h=50&mask=circle)](https://github.com/felixwang9817)[![64864908](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/64864908?v=4&w=50&h=50&mask=circle)](https://github.com/xshen8888)[![10430635](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10430635?v=4&w=50&h=50&mask=circle)](https://github.com/juandiegopalomino)[![31911175](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/31911175?v=4&w=50&h=50&mask=circle)](https://github.com/kanyesthaker)[![104152793](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/104152793?v=4&w=50&h=50&mask=circle)](https://github.com/marc-union)[![27818609](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/27818609?v=4&w=50&h=50&mask=circle)](https://github.com/michaeltinsley)[![22797900](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22797900?v=4&w=50&h=50&mask=circle)](https://github.com/stolarczyk)[![6486584](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6486584?v=4&w=50&h=50&mask=circle)](https://github.com/mucahitkantepe)[![321459](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/321459?v=4&w=50&h=50&mask=circle)](https://github.com/oyevtushok)[![405480](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/405480?v=4&w=50&h=50&mask=circle)](https://github.com/georgesnelling)[![54046807](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54046807?v=4&w=50&h=50&mask=circle)](https://github.com/kamaleybov)[![1004789](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1004789?v=4&w=50&h=50&mask=circle)](https://github.com/dschaller)[![1659415](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1659415?v=4&w=50&h=50&mask=circle)](https://github.com/dav009)[![1031759](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1031759?v=4&w=50&h=50&mask=circle)](https://github.com/agiron123)[![107633597](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/107633597?v=4&w=50&h=50&mask=circle)](https://github.com/peterghaddad)[![136724527](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/136724527?v=4&w=50&h=50&mask=circle)](https://github.com/Murdock9803)[![50983601](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/50983601?v=4&w=50&h=50&mask=circle)](https://github.com/zychen5186)[![69161722](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/69161722?v=4&w=50&h=50&mask=circle)](https://github.com/noobkid2411)[![24486999](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24486999?v=4&w=50&h=50&mask=circle)](https://github.com/suravshrestha)[![144381122](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/144381122?v=4&w=50&h=50&mask=circle)](https://github.com/vraiyaninv)[![43336767](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43336767?v=4&w=50&h=50&mask=circle)](https://github.com/yongchand)[![36594527](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36594527?v=4&w=50&h=50&mask=circle)](https://github.com/mishmanners)[![86911142](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/86911142?v=4&w=50&h=50&mask=circle)](https://github.com/idivyanshbansal)[![25391173](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25391173?v=4&w=50&h=50&mask=circle)](https://github.com/nicklofaso)[![380927](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/380927?v=4&w=50&h=50&mask=circle)](https://github.com/cpaulik)[![480621](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/480621?v=4&w=50&h=50&mask=circle)](https://github.com/davidxia)[![1335881](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1335881?v=4&w=50&h=50&mask=circle)](https://github.com/hoyajigi)[![100597998](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/100597998?v=4&w=50&h=50&mask=circle)](https://github.com/MrKrishnaAgarwal)[![4830700](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4830700?v=4&w=50&h=50&mask=circle)](https://github.com/NitinAgg)[![790725](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/790725?v=4&w=50&h=50&mask=circle)](https://github.com/rodrigobaron)[![10438373](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10438373?v=4&w=50&h=50&mask=circle)](https://github.com/SKalt)[![24543401](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24543401?v=4&w=50&h=50&mask=circle)](https://github.com/asoundarya96)[![141538510](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/141538510?v=4&w=50&h=50&mask=circle)](https://github.com/SophieTech88)[![47355538](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/47355538?v=4&w=50&h=50&mask=circle)](https://github.com/siiddhantt)[![46835608](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46835608?v=4&w=50&h=50&mask=circle)](https://github.com/shreyas44)[![119912892](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/119912892?v=4&w=50&h=50&mask=circle)](https://github.com/Virtual4087)[![93093775](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/93093775?v=4&w=50&h=50&mask=circle)](https://github.com/Ash0807)[![33272587](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/33272587?v=4&w=50&h=50&mask=circle)](https://github.com/samuel-sujith)[![580328](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/580328?v=4&w=50&h=50&mask=circle)](https://github.com/ilikedata)[![26265392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26265392?v=4&w=50&h=50&mask=circle)](https://github.com/ttanay)[![7144772](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7144772?v=4&w=50&h=50&mask=circle)](https://github.com/sighingnow)[![61864060](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/61864060?v=4&w=50&h=50&mask=circle)](https://github.com/HuangTing-Yao)[![1027207](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1027207?v=4&w=50&h=50&mask=circle)](https://github.com/orf)[![22917741](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22917741?v=4&w=50&h=50&mask=circle)](https://github.com/gigi-at-zymergen)[![36989112](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36989112?v=4&w=50&h=50&mask=circle)](https://github.com/nishantwrp)[![260015](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/260015?v=4&w=50&h=50&mask=circle)](https://github.com/ossareh)[![54034701](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/54034701?v=4&w=50&h=50&mask=circle)](https://github.com/peterxcli)[![8755869](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8755869?v=4&w=50&h=50&mask=circle)](https://github.com/paravatha)[![141313113](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/141313113?v=4&w=50&h=50&mask=circle)](https://github.com/robert-ulbrich-mercedes-benz)[![6528449](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6528449?v=4&w=50&h=50&mask=circle)](https://github.com/uschi2000)[![576968](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/576968?v=4&w=50&h=50&mask=circle)](https://github.com/ronaldosaheki)[![10095462](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10095462?v=4&w=50&h=50&mask=circle)](https://github.com/GRomR1)[![48779231](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48779231?v=4&w=50&h=50&mask=circle)](https://github.com/SZL741023)[![144255851](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/144255851?v=4&w=50&h=50&mask=circle)](https://github.com/Sennuno)[![36827492](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36827492?v=4&w=50&h=50&mask=circle)](https://github.com/shahwar9)[![34468461](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/34468461?v=4&w=50&h=50&mask=circle)](https://github.com/sshardool)[![1908193](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1908193?v=4&w=50&h=50&mask=circle)](https://github.com/shengyu7697)[![133936](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/133936?v=4&w=50&h=50&mask=circle)](https://github.com/shihgianlee)[![40143026](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/40143026?v=4&w=50&h=50&mask=circle)](https://github.com/hampusrosvall)[![77197126](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/77197126?v=4&w=50&h=50&mask=circle)](https://github.com/hitarth01)[![300315](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/300315?v=4&w=50&h=50&mask=circle)](https://github.com/jcourteau)[![1220444](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1220444?v=4&w=50&h=50&mask=circle)](https://github.com/jkhales)[![106815366](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/106815366?v=4&w=50&h=50&mask=circle)](https://github.com/jw0515)[![1568889](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1568889?v=4&w=50&h=50&mask=circle)](https://github.com/leorleor)[![168411899](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/168411899?v=4&w=50&h=50&mask=circle)](https://github.com/mthemis-provenir)[![937967](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/937967?v=4&w=50&h=50&mask=circle)](https://github.com/moose007)[![73983677](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/73983677?v=4&w=50&h=50&mask=circle)](https://github.com/omahs)[![114232404](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/114232404?v=4&w=50&h=50&mask=circle)](https://github.com/sanjaychouhan-adf)[![11962777](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11962777?v=4&w=50&h=50&mask=circle)](https://github.com/ssen85)[![14996868](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14996868?v=4&w=50&h=50&mask=circle)](https://github.com/v01dXYZ)[![93438190](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/93438190?v=4&w=50&h=50&mask=circle)](https://github.com/wanderer163)[![78115767](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/78115767?v=4&w=50&h=50&mask=circle)](https://github.com/trevormcguire)[![16526627](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16526627?v=4&w=50&h=50&mask=circle)](https://github.com/vijaysaravana)[![697033](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/697033?v=4&w=50&h=50&mask=circle)](https://github.com/vglocus)[![2272137](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2272137?v=4&w=50&h=50&mask=circle)](https://github.com/Dlougach)[![39889](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/39889?v=4&w=50&h=50&mask=circle)](https://github.com/yarikoptic)[![12821510](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12821510?v=4&w=50&h=50&mask=circle)](https://github.com/ongkong)[![26526132](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26526132?v=4&w=50&h=50&mask=circle)](https://github.com/bearomorphism)[![44134607](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/44134607?v=4&w=50&h=50&mask=circle)](https://github.com/chmod77)[![43691987](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43691987?v=4&w=50&h=50&mask=circle)](https://github.com/desihsu)[![5346764](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5346764?v=4&w=50&h=50&mask=circle)](https://github.com/fsz285)[![143190185](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/143190185?v=4&w=50&h=50&mask=circle)](https://github.com/gdabisias)[![11796986](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11796986?v=4&w=50&h=50&mask=circle)](https://github.com/avan-sh)[![489331](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/489331?v=4&w=50&h=50&mask=circle)](https://github.com/brndnblck)[![304786](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/304786?v=4&w=50&h=50&mask=circle)](https://github.com/kinow)[![160060](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/160060?v=4&w=50&h=50&mask=circle)](https://github.com/ctso)[![156356273](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/156356273?v=4&w=50&h=50&mask=circle)](https://github.com/cratiu222)[![24402505](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/24402505?v=4&w=50&h=50&mask=circle)](https://github.com/Daeruin)[![102558755](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/102558755?v=4&w=50&h=50&mask=circle)](https://github.com/dyu-bot)[![146735585](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/146735585?v=4&w=50&h=50&mask=circle)](https://github.com/nnsW3)[![20135478](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20135478?v=4&w=50&h=50&mask=circle)](https://github.com/Juneezee)[![1627021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1627021?v=4&w=50&h=50&mask=circle)](https://github.com/EraYaN)[![68840528](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/68840528?v=4&w=50&h=50&mask=circle)](https://github.com/vincent0426)[![64676594](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/64676594?v=4&w=50&h=50&mask=circle)](https://github.com/abhijeet007rocks8)[![132337675](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/132337675?v=4&w=50&h=50&mask=circle)](https://github.com/adarsh-jha-dev)[![1627770](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1627770?v=4&w=50&h=50&mask=circle)](https://github.com/amitani)[![128223364](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/128223364?v=4&w=50&h=50&mask=circle)](https://github.com/blindaks)[![66388192](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/66388192?v=4&w=50&h=50&mask=circle)](https://github.com/mounesi)[![13237080](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13237080?v=4&w=50&h=50&mask=circle)](https://github.com/aminmaghsodi)[![14992189](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14992189?v=4&w=50&h=50&mask=circle)](https://github.com/eanakhl)[![1175392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1175392?v=4&w=50&h=50&mask=circle)](https://github.com/adinin)[![26172355](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26172355?v=4&w=50&h=50&mask=circle)](https://github.com/ALMerrill)[![48056316](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48056316?v=4&w=50&h=50&mask=circle)](https://github.com/ap0calypse8)[![7475946](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7475946?v=4&w=50&h=50&mask=circle)](https://github.com/anton-malakhov)[![1174730](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1174730?v=4&w=50&h=50&mask=circle)](https://github.com/mouuff)[![1633460](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1633460?v=4&w=50&h=50&mask=circle)](https://github.com/jmcarp)[![44368997](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/44368997?v=4&w=50&h=50&mask=circle)](https://github.com/radiantly)[![16404204](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16404204?v=4&w=50&h=50&mask=circle)](https://github.com/Jeinhaus)[![9060786](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9060786?v=4&w=50&h=50&mask=circle)](https://github.com/HansBambel)[![3033592](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3033592?v=4&w=50&h=50&mask=circle)](https://github.com/kazesberger)[![13591898](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13591898?v=4&w=50&h=50&mask=circle)](https://github.com/lauralindy)[![19229049](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19229049?v=4&w=50&h=50&mask=circle)](https://github.com/lsena)[![6958772](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6958772?v=4&w=50&h=50&mask=circle)](https://github.com/marrrcin)[![123787712](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/123787712?v=4&w=50&h=50&mask=circle)](https://github.com/mark-thm)[![2236795](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2236795?v=4&w=50&h=50&mask=circle)](https://github.com/mhotan)[![10829864](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10829864?v=4&w=50&h=50&mask=circle)](https://github.com/mcanueste)[![11456773](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11456773?v=4&w=50&h=50&mask=circle)](https://github.com/fvde)[![6987428](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6987428?v=4&w=50&h=50&mask=circle)](https://github.com/guyarad)[![1596283](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1596283?v=4&w=50&h=50&mask=circle)](https://github.com/guy4261)[![7490199](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7490199?v=4&w=50&h=50&mask=circle)](https://github.com/Lundez)[![10345184](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10345184?v=4&w=50&h=50&mask=circle)](https://github.com/hasukmistry)[![91054457](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/91054457?v=4&w=50&h=50&mask=circle)](https://github.com/HeetVekariya)[![29532638](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/29532638?v=4&w=50&h=50&mask=circle)](https://github.com/rokrokss)[![22633385](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22633385?v=4&w=50&h=50&mask=circle)](https://github.com/eltociear)[![151841](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/151841?v=4&w=50&h=50&mask=circle)](https://github.com/goodgravy)[![46633758](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/46633758?v=4&w=50&h=50&mask=circle)](https://github.com/jsong336)[![14008978](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14008978?v=4&w=50&h=50&mask=circle)](https://github.com/jeremydonahue)[![9272376](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9272376?v=4&w=50&h=50&mask=circle)](https://github.com/jonasdebeukelaer)[![1043051](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1043051?v=4&w=50&h=50&mask=circle)](https://github.com/kylewaynebenson)[![21953442](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/21953442?v=4&w=50&h=50&mask=circle)](https://github.com/Gui11aum3)[![16461847](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16461847?v=4&w=50&h=50&mask=circle)](https://github.com/JakeNeyer)[![299421](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/299421?v=4&w=50&h=50&mask=circle)](https://github.com/aliavni)[![2845540](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2845540?v=4&w=50&h=50&mask=circle)](https://github.com/RustedBones)[![4056828](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4056828?v=4&w=50&h=50&mask=circle)](https://github.com/pablocasares)[![138898](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/138898?v=4&w=50&h=50&mask=circle)](https://github.com/andyczerwonka)[![150935185](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/150935185?v=4&w=50&h=50&mask=circle)](https://github.com/jschuchart-spot)[![471021](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/471021?v=4&w=50&h=50&mask=circle)](https://github.com/marschall)[![5732047](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5732047?v=4&w=50&h=50&mask=circle)](https://github.com/stormy-ua)[![1071153](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1071153?v=4&w=50&h=50&mask=circle)](https://github.com/evdokim)[![13670774](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13670774?v=4&w=50&h=50&mask=circle)](https://github.com/AndersonReyes)[![438217](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/438217?v=4&w=50&h=50&mask=circle)](https://github.com/acet)[![71284190](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/71284190?v=4&w=50&h=50&mask=circle)](https://github.com/gdungca-fn)[![85021780](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/85021780?v=4&w=50&h=50&mask=circle)](https://github.com/Abdullahi-Ahmed)[![48512530](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48512530?v=4&w=50&h=50&mask=circle)](https://github.com/amaleelhamri)[![3275593](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3275593?v=4&w=50&h=50&mask=circle)](https://github.com/pradyunsg)[![66853113](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/68672?v=4&w=50&h=50&mask=circle)](https://github.com/apps/pre-commit-ci)[![1834509](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1834509?v=4&w=50&h=50&mask=circle)](https://github.com/jdknight)[![107893](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/107893?v=4&w=50&h=50&mask=circle)](https://github.com/kmike)[![1324225](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1324225?v=4&w=50&h=50&mask=circle)](https://github.com/hugovk)[![1300022](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1300022?v=4&w=50&h=50&mask=circle)](https://github.com/sirosen)[![244656](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/244656?v=4&w=50&h=50&mask=circle)](https://github.com/humitos)[![467294](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/467294?v=4&w=50&h=50&mask=circle)](https://github.com/bastimeyer)[![71486](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/71486?v=4&w=50&h=50&mask=circle)](https://github.com/asmeurer)[![20280470](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20280470?v=4&w=50&h=50&mask=circle)](https://github.com/drewyh)[![3533182](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3533182?v=4&w=50&h=50&mask=circle)](https://github.com/polyzen)[![199429](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/199429?v=4&w=50&h=50&mask=circle)](https://github.com/dvarrazzo)[![1032633](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1032633?v=4&w=50&h=50&mask=circle)](https://github.com/dbitouze)[![1313087](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1313087?v=4&w=50&h=50&mask=circle)](https://github.com/idryzhov)[![521097](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/521097?v=4&w=50&h=50&mask=circle)](https://github.com/pauloxnet)[![63936253](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/63936253?v=4&w=50&h=50&mask=circle)](https://github.com/ichard26)[![18519037](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18519037?v=4&w=50&h=50&mask=circle)](https://github.com/sethmlarson)[![413772](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/413772?v=4&w=50&h=50&mask=circle)](https://github.com/graingert)[![11478411](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11478411?v=4&w=50&h=50&mask=circle)](https://github.com/stonecharioteer)[![6739793](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6739793?v=4&w=50&h=50&mask=circle)](https://github.com/yeraydiazdiaz)[![83365562](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/83365562?v=4&w=50&h=50&mask=circle)](https://github.com/eviau-sat)[![6670894](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6670894?v=4&w=50&h=50&mask=circle)](https://github.com/rozsasarpi)[![86675](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/86675?v=4&w=50&h=50&mask=circle)](https://github.com/estan)[![4748863](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4748863?v=4&w=50&h=50&mask=circle)](https://github.com/pseudomuto)[![181308](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/181308?v=4&w=50&h=50&mask=circle)](https://github.com/htdvisser)[![1390277](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1390277?v=4&w=50&h=50&mask=circle)](https://github.com/jacobtolar)[![1391982](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1391982?v=4&w=50&h=50&mask=circle)](https://github.com/ezimanyi)[![135130171](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/135130171?v=4&w=50&h=50&mask=circle)](https://github.com/hmacias-avaya)[![3880001](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3880001?v=4&w=50&h=50&mask=circle)](https://github.com/lpabon)[![770392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/770392?v=4&w=50&h=50&mask=circle)](https://github.com/ArcEye)[![6178510](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6178510?v=4&w=50&h=50&mask=circle)](https://github.com/mingrammer)[![5111931](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5111931?v=4&w=50&h=50&mask=circle)](https://github.com/aschrijver)[![148219809](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/148219809?v=4&w=50&h=50&mask=circle)](https://github.com/panzerfahrer)[![16724](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16724?v=4&w=50&h=50&mask=circle)](https://github.com/glasser)[![17330872](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17330872?v=4&w=50&h=50&mask=circle)](https://github.com/murph0)[![419419](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/419419?v=4&w=50&h=50&mask=circle)](https://github.com/zetaron)[![1014](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1014?v=4&w=50&h=50&mask=circle)](https://github.com/sunfmin)[![504507](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/504507?v=4&w=50&h=50&mask=circle)](https://github.com/guozheng)[![8841470](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8841470?v=4&w=50&h=50&mask=circle)](https://github.com/suusan2go)[![901479](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/901479?v=4&w=50&h=50&mask=circle)](https://github.com/mhaberler)[![353644](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/353644?v=4&w=50&h=50&mask=circle)](https://github.com/dreampuf)[![12421077](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/12421077?v=4&w=50&h=50&mask=circle)](https://github.com/UnicodingUnicorn)[![809865](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/809865?v=4&w=50&h=50&mask=circle)](https://github.com/philiptzou)[![19378](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/19378?v=4&w=50&h=50&mask=circle)](https://github.com/timabell)[![614934](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/614934?v=4&w=50&h=50&mask=circle)](https://github.com/adzenith)[![1113245](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1113245?v=4&w=50&h=50&mask=circle)](https://github.com/jasonhancock)[![101659](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/101659?v=4&w=50&h=50&mask=circle)](https://github.com/matryer)[![4730508](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/4730508?v=4&w=50&h=50&mask=circle)](https://github.com/piotrrojek)[![33036160](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/33036160?v=4&w=50&h=50&mask=circle)](https://github.com/jasonsattler)[![470810](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/470810?v=4&w=50&h=50&mask=circle)](https://github.com/sbward)[![7592392](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7592392?v=4&w=50&h=50&mask=circle)](https://github.com/Pisush)[![94814](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/94814?v=4&w=50&h=50&mask=circle)](https://github.com/tamalsaha)[![8147854](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8147854?v=4&w=50&h=50&mask=circle)](https://github.com/marianina8)[![1683714](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1683714?v=4&w=50&h=50&mask=circle)](https://github.com/naysayer)[![2807589](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2807589?v=4&w=50&h=50&mask=circle)](https://github.com/darwayne)[![1005](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1005?v=4&w=50&h=50&mask=circle)](https://github.com/ernesto-jimenez)[![17263167](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17263167?v=4&w=50&h=50&mask=circle)](https://github.com/jsteenb2)[![6386887](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6386887?v=4&w=50&h=50&mask=circle)](https://github.com/AgrimPrasad)[![615811](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/615811?v=4&w=50&h=50&mask=circle)](https://github.com/dahernan)[![75184](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/75184?v=4&w=50&h=50&mask=circle)](https://github.com/jtarchie)[![469669](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/469669?v=4&w=50&h=50&mask=circle)](https://github.com/jdtobe)[![28523](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/28523?v=4&w=50&h=50&mask=circle)](https://github.com/alrs)[![426880](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/426880?v=4&w=50&h=50&mask=circle)](https://github.com/tkent)[![10113228](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10113228?v=4&w=50&h=50&mask=circle)](https://github.com/urisimchoni)[![5751464](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5751464?v=4&w=50&h=50&mask=circle)](https://github.com/Xercoy)[![2405410](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2405410?v=4&w=50&h=50&mask=circle)](https://github.com/marbergq)[![5082160](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5082160?v=4&w=50&h=50&mask=circle)](https://github.com/anothrNick)[![11335612](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11335612?v=4&w=50&h=50&mask=circle)](https://github.com/fermoya)[![23391642](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/23391642?v=4&w=50&h=50&mask=circle)](https://github.com/sbe-arg)[![1024762](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1024762?v=4&w=50&h=50&mask=circle)](https://github.com/PeerXu)[![7390781](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7390781?v=4&w=50&h=50&mask=circle)](https://github.com/reececomo)[![49680](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49680?v=4&w=50&h=50&mask=circle)](https://github.com/dmerrick)[![87524](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/87524?v=4&w=50&h=50&mask=circle)](https://github.com/andrewcole)[![866505](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/866505?v=4&w=50&h=50&mask=circle)](https://github.com/phish108)[![2611549](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2611549?v=4&w=50&h=50&mask=circle)](https://github.com/endrjuskr)[![8232503](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8232503?v=4&w=50&h=50&mask=circle)](https://github.com/sjauld)[![118945041](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/118945041?v=4&w=50&h=50&mask=circle)](https://github.com/vq-ambiata)[![3807434](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3807434?v=4&w=50&h=50&mask=circle)](https://github.com/tomsolem)[![16513382](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16513382?v=4&w=50&h=50&mask=circle)](https://github.com/117)[![8320753](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8320753?v=4&w=50&h=50&mask=circle)](https://github.com/lovromazgon)[![5655837](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5655837?v=4&w=50&h=50&mask=circle)](https://github.com/gukoff)[![49961058](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/49961058?v=4&w=50&h=50&mask=circle)](https://github.com/bevans-HD)[![25625597](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25625597?v=4&w=50&h=50&mask=circle)](https://github.com/zero-below)[![62775347](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/62775347?v=4&w=50&h=50&mask=circle)](https://github.com/okozachenko1203)[![53085803](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/53085803?v=4&w=50&h=50&mask=circle)](https://github.com/cuttingedge1109)[![5067549](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5067549?v=4&w=50&h=50&mask=circle)](https://github.com/pellared)[![25486791](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25486791?v=4&w=50&h=50&mask=circle)](https://github.com/pavyarov)[![995707](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/995707?v=4&w=50&h=50&mask=circle)](https://github.com/OskarStark)[![2302957](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/2302957?v=4&w=50&h=50&mask=circle)](https://github.com/JeremyLWright)[![10090384](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10090384?v=4&w=50&h=50&mask=circle)](https://github.com/ivanpk)[![17337515](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17337515?v=4&w=50&h=50&mask=circle)](https://github.com/fabricepipart)[![8296645](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8296645?v=4&w=50&h=50&mask=circle)](https://github.com/imdanielsp)[![6388483](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6388483?v=4&w=50&h=50&mask=circle)](https://github.com/zsedem)[![69170839](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/69170839?v=4&w=50&h=50&mask=circle)](https://github.com/adam-berrio)[![282792](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/282792?v=4&w=50&h=50&mask=circle)](https://github.com/asford)[![38894122](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/38894122?v=4&w=50&h=50&mask=circle)](https://github.com/bmcconeghy)[![16698198](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/16698198?v=4&w=50&h=50&mask=circle)](https://github.com/conda-forge-admin)[![36490558](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/36490558?v=4&w=50&h=50&mask=circle)](https://github.com/regro-cf-autotick-bot)[![79913779](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/102928?v=4&w=50&h=50&mask=circle)](https://github.com/apps/conda-forge-curator)[![41898282](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/in/15368?v=4&w=50&h=50&mask=circle)](https://github.com/apps/github-actions)[![18567580](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/18567580?v=4&w=50&h=50&mask=circle)](https://github.com/conda-forge-linter)[![72671586](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/72671586?v=4&w=50&h=50&mask=circle)](https://github.com/pheianox)[![3760025](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3760025?v=4&w=50&h=50&mask=circle)](https://github.com/gaga5lala)[![115705553](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/115705553?v=4&w=50&h=50&mask=circle)](https://github.com/divyank000) ## License From 7aeaa26816ef0d0f7d07252483d9de4136b78b88 Mon Sep 17 00:00:00 2001 From: luckyarthur <14682479+luckyarthur@users.noreply.github.com> Date: Fri, 27 Dec 2024 04:12:02 +0800 Subject: [PATCH 04/15] Improve resource manager test coverage (#5973) * GetWorkflowAttributes error test case Signed-off-by: Arthur * add UpdateWorkflowAttributes error with no attributes test case Signed-off-by: Arthur * add DeleteWorkflowAttributes error test case Signed-off-by: Arthur * add DeleteProjectAttributes error test cases Signed-off-by: Arthur * add UpdateProjectDomainAttributes error test case Signed-off-by: Arthur * add GetProjectDomainAttributes error test case Signed-off-by: Arthur * add DeleteProjectDomainAttributes error test case Signed-off-by: Arthur * add ListAll error test case Signed-off-by: Arthur * add check if the UpdateWorkflowAttributes return the FlyteAdminError Signed-off-by: Arthur * add check if GetWorkflowAttributes return FlyteAdminError type Signed-off-by: Arthur * add check of error type for validation and Delete Function error Signed-off-by: Arthur * add error message assert for DeleteWorkflowAttributes validate and delete function error Signed-off-by: Arthur * add error message assert for DeleteProjectAttributes validate and delete function error Signed-off-by: Arthur * add error message assert for GetWorkflowAttributes validate and Get function error Signed-off-by: Arthur * add error message check for UpdateWorkflowAttributes domain error Signed-off-by: Arthur * add validate and empty request attribute instance error type check and error message check for UpdateProjectDomainAttributes Signed-off-by: Arthur * add validate and project domain error type and error message check Signed-off-by: Arthur * add delete function fail and validate error type and message check for DeleteProjectDomainAttributes Signed-off-by: Arthur * add resource error type and message check for ListAll test Signed-off-by: Arthur --------- Signed-off-by: Arthur Signed-off-by: Eduardo Apolinario Co-authored-by: Eduardo Apolinario --- .../impl/resources/resource_manager_test.go | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) diff --git a/flyteadmin/pkg/manager/impl/resources/resource_manager_test.go b/flyteadmin/pkg/manager/impl/resources/resource_manager_test.go index be03d642ab..9c5afde393 100644 --- a/flyteadmin/pkg/manager/impl/resources/resource_manager_test.go +++ b/flyteadmin/pkg/manager/impl/resources/resource_manager_test.go @@ -54,6 +54,15 @@ func TestUpdateWorkflowAttributes(t *testing.T) { _, err := manager.UpdateWorkflowAttributes(context.Background(), request) assert.Nil(t, err) assert.True(t, createOrUpdateCalled) + + request = &admin.WorkflowAttributesUpdateRequest{ + Attributes: &admin.WorkflowAttributes{}, + } + _, failError := manager.UpdateWorkflowAttributes(context.Background(), request) + assert.Error(t, failError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, failError, &newError) + assert.Equal(t, newError.Error(), "domain [] is unrecognized by system") } func TestUpdateWorkflowAttributes_CreateOrMerge(t *testing.T) { @@ -181,6 +190,40 @@ func TestGetWorkflowAttributes(t *testing.T) { MatchingAttributes: testutils.ExecutionQueueAttributes, }, }, response)) + + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = func( + ctx context.Context, projectID string) (models.Project, error) { + return models.Project{}, errors.NewFlyteAdminError(codes.NotFound, "validationError") + } + + _, validationError := manager.GetWorkflowAttributes(context.Background(), request) + assert.Error(t, validationError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, validationError, &newError) + assert.Equal(t, newError.Error(), "failed to validate that project [project] and domain [domain] are registered, err: [validationError]") + + db.ResourceRepo().(*mocks.MockResourceRepo).GetFunction = func( + ctx context.Context, ID repoInterfaces.ResourceID) (models.Resource, error) { + assert.Equal(t, project, ID.Project) + assert.Equal(t, domain, ID.Domain) + assert.Equal(t, workflow, ID.Workflow) + assert.Equal(t, admin.MatchableResource_EXECUTION_QUEUE.String(), ID.ResourceType) + expectedSerializedAttrs, _ := proto.Marshal(testutils.ExecutionQueueAttributes) + return models.Resource{ + Project: project, + Domain: domain, + Workflow: workflow, + ResourceType: "resource", + Attributes: expectedSerializedAttrs, + }, errors.NewFlyteAdminError(codes.NotFound, "workflowAttributesModelError") + } + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = mocks.NewMockRepository().ProjectRepo().(*mocks.MockProjectRepo).GetFunction + + _, failError := manager.GetWorkflowAttributes(context.Background(), request) + assert.Error(t, failError) + var secondError errors.FlyteAdminError + assert.ErrorAs(t, failError, &secondError) + assert.Equal(t, secondError.Error(), "workflowAttributesModelError") } func TestDeleteWorkflowAttributes(t *testing.T) { @@ -202,6 +245,33 @@ func TestDeleteWorkflowAttributes(t *testing.T) { manager := NewResourceManager(db, testutils.GetApplicationConfigWithDefaultDomains()) _, err := manager.DeleteWorkflowAttributes(context.Background(), request) assert.Nil(t, err) + + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = func( + ctx context.Context, projectID string) (models.Project, error) { + return models.Project{}, errors.NewFlyteAdminError(codes.NotFound, "validationError") + } + _, validationError := manager.DeleteWorkflowAttributes(context.Background(), request) + assert.Error(t, validationError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, validationError, &newError) + assert.Equal(t, newError.Error(), "failed to validate that project [project] and domain [domain] are registered, err: [validationError]") + + db.ResourceRepo().(*mocks.MockResourceRepo).DeleteFunction = func( + ctx context.Context, ID repoInterfaces.ResourceID) error { + assert.Equal(t, project, ID.Project) + assert.Equal(t, domain, ID.Domain) + assert.Equal(t, workflow, ID.Workflow) + assert.Equal(t, admin.MatchableResource_EXECUTION_QUEUE.String(), ID.ResourceType) + return errors.NewFlyteAdminError(codes.NotFound, "deleteError") + } + //cause we use reference of ProjectRepo GetFunction, need to reset to default GetFunction + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = mocks.NewMockRepository().ProjectRepo().(*mocks.MockProjectRepo).GetFunction + + _, failError := manager.DeleteWorkflowAttributes(context.Background(), request) + assert.Error(t, failError) + var secondError errors.FlyteAdminError + assert.ErrorAs(t, failError, &secondError) + assert.Equal(t, secondError.Error(), "deleteError") } func TestUpdateProjectDomainAttributes(t *testing.T) { @@ -229,6 +299,27 @@ func TestUpdateProjectDomainAttributes(t *testing.T) { _, err := manager.UpdateProjectDomainAttributes(context.Background(), request) assert.Nil(t, err) assert.True(t, createOrUpdateCalled) + + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = func( + ctx context.Context, projectID string) (models.Project, error) { + return models.Project{}, errors.NewFlyteAdminError(codes.NotFound, "validationError") + } + _, validationError := manager.UpdateProjectDomainAttributes(context.Background(), request) + assert.Error(t, validationError) + var secondError errors.FlyteAdminError + assert.ErrorAs(t, validationError, &secondError) + assert.Equal(t, secondError.Error(), "failed to validate that project [project] and domain [domain] are registered, err: [validationError]") + + request = &admin.ProjectDomainAttributesUpdateRequest{ + Attributes: &admin.ProjectDomainAttributes{}, + } + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = mocks.NewMockRepository().ProjectRepo().(*mocks.MockProjectRepo).GetFunction + + _, attributesError := manager.UpdateProjectDomainAttributes(context.Background(), request) + assert.Error(t, attributesError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, attributesError, &newError) + assert.Equal(t, newError.Error(), "domain [] is unrecognized by system") } func TestUpdateProjectDomainAttributes_CreateOrMerge(t *testing.T) { @@ -349,6 +440,37 @@ func TestGetProjectDomainAttributes(t *testing.T) { MatchingAttributes: testutils.ExecutionQueueAttributes, }, }, response)) + + db.ResourceRepo().(*mocks.MockResourceRepo).GetFunction = func( + ctx context.Context, ID repoInterfaces.ResourceID) (models.Resource, error) { + assert.Equal(t, project, ID.Project) + assert.Equal(t, domain, ID.Domain) + assert.Equal(t, "", ID.Workflow) + assert.Equal(t, admin.MatchableResource_EXECUTION_QUEUE.String(), ID.ResourceType) + expectedSerializedAttrs, _ := proto.Marshal(testutils.ExecutionQueueAttributes) + return models.Resource{ + Project: project, + Domain: domain, + ResourceType: "resource", + Attributes: expectedSerializedAttrs, + }, errors.NewFlyteAdminError(codes.NotFound, "projectDomainError") + } + _, projectDomainError := manager.GetProjectDomainAttributes(context.Background(), request) + assert.Error(t, projectDomainError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, projectDomainError, &newError) + assert.Equal(t, newError.Error(), "projectDomainError") + + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = func( + ctx context.Context, projectID string) (models.Project, error) { + return models.Project{}, errors.NewFlyteAdminError(codes.NotFound, "validationError") + } + _, validationError := manager.GetProjectDomainAttributes(context.Background(), request) + assert.Error(t, validationError) + var secondError errors.FlyteAdminError + assert.ErrorAs(t, validationError, &secondError) + assert.Equal(t, secondError.Error(), "failed to validate that project [project] and domain [domain] are registered, err: [validationError]") + } func TestDeleteProjectDomainAttributes(t *testing.T) { @@ -368,6 +490,29 @@ func TestDeleteProjectDomainAttributes(t *testing.T) { manager := NewResourceManager(db, testutils.GetApplicationConfigWithDefaultDomains()) _, err := manager.DeleteProjectDomainAttributes(context.Background(), request) assert.Nil(t, err) + + db.ResourceRepo().(*mocks.MockResourceRepo).DeleteFunction = func( + ctx context.Context, ID repoInterfaces.ResourceID) error { + assert.Equal(t, project, ID.Project) + assert.Equal(t, domain, ID.Domain) + assert.Equal(t, admin.MatchableResource_EXECUTION_QUEUE.String(), ID.ResourceType) + return errors.NewFlyteAdminError(codes.NotFound, "failError") + } + _, failError := manager.DeleteProjectDomainAttributes(context.Background(), request) + assert.Error(t, failError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, failError, &newError) + assert.Equal(t, newError.Error(), "failError") + + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = func( + ctx context.Context, projectID string) (models.Project, error) { + return models.Project{}, errors.NewFlyteAdminError(codes.NotFound, "validationError") + } + _, validationError := manager.DeleteProjectDomainAttributes(context.Background(), request) + assert.Error(t, validationError) + var secondError errors.FlyteAdminError + assert.ErrorAs(t, validationError, &secondError) + assert.Equal(t, secondError.Error(), "failed to validate that project [project] and domain [domain] are registered, err: [validationError]") } func TestUpdateProjectAttributes(t *testing.T) { @@ -679,6 +824,31 @@ func TestDeleteProjectAttributes(t *testing.T) { manager := NewResourceManager(db, testutils.GetApplicationConfigWithDefaultDomains()) _, err := manager.DeleteProjectAttributes(context.Background(), request) assert.Nil(t, err) + + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = func( + ctx context.Context, projectID string) (models.Project, error) { + return models.Project{}, errors.NewFlyteAdminError(codes.NotFound, "validationError") + } + _, validationError := manager.DeleteProjectAttributes(context.Background(), request) + assert.Error(t, validationError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, validationError, &newError) + assert.Equal(t, newError.Error(), "failed to validate that project [project] is registered, err: [validationError]") + + db.ResourceRepo().(*mocks.MockResourceRepo).DeleteFunction = func( + ctx context.Context, ID repoInterfaces.ResourceID) error { + assert.Equal(t, project, ID.Project) + assert.Equal(t, "", ID.Domain) + assert.Equal(t, admin.MatchableResource_WORKFLOW_EXECUTION_CONFIG.String(), ID.ResourceType) + return errors.NewFlyteAdminError(codes.NotFound, "deleteError") + } + db.ProjectRepo().(*mocks.MockProjectRepo).GetFunction = mocks.NewMockRepository().ProjectRepo().(*mocks.MockProjectRepo).GetFunction + + _, failError := manager.DeleteProjectAttributes(context.Background(), request) + assert.Error(t, failError) + var secondError errors.FlyteAdminError + assert.ErrorAs(t, failError, &secondError) + assert.Equal(t, secondError.Error(), "deleteError") } func TestGetResource(t *testing.T) { @@ -775,4 +945,41 @@ func TestListAllResources(t *testing.T) { Workflow: "workflow", Attributes: &workflowAttributes, }, response.GetConfigurations()[1])) + + db.ResourceRepo().(*mocks.MockResourceRepo).ListAllFunction = func(ctx context.Context, resourceType string) ( + []models.Resource, error) { + assert.Equal(t, admin.MatchableResource_CLUSTER_RESOURCE.String(), resourceType) + return []models.Resource{ + { + Project: "projectA", + ResourceType: admin.MatchableResource_CLUSTER_RESOURCE.String(), + Attributes: marshaledProjectAttrs, + }, + { + Project: "projectB", + Domain: "development", + Workflow: "workflow", + ResourceType: admin.MatchableResource_CLUSTER_RESOURCE.String(), + Attributes: marshaledWorkflowAttrs, + }, + }, errors.NewFlyteAdminError(codes.NotFound, "resourceError") + } + + _, resourceError := manager.ListAll(context.Background(), &admin.ListMatchableAttributesRequest{ + ResourceType: admin.MatchableResource_CLUSTER_RESOURCE, + }) + assert.Error(t, resourceError) + var newError errors.FlyteAdminError + assert.ErrorAs(t, resourceError, &newError) + assert.Equal(t, newError.Error(), "resourceError") + + db.ResourceRepo().(*mocks.MockResourceRepo).ListAllFunction = func(ctx context.Context, resourceType string) ( + []models.Resource, error) { + assert.Equal(t, admin.MatchableResource_CLUSTER_RESOURCE.String(), resourceType) + return nil, nil + } + emptyResource, _ := manager.ListAll(context.Background(), &admin.ListMatchableAttributesRequest{ + ResourceType: admin.MatchableResource_CLUSTER_RESOURCE, + }) + assert.Equal(t, &admin.ListMatchableAttributesResponse{}, emptyResource, "The two values should be equal") } From bf38993600603b6e47394bdecc5ef6c9905e7076 Mon Sep 17 00:00:00 2001 From: ketian-indeed <136042789+ketian-indeed@users.noreply.github.com> Date: Fri, 27 Dec 2024 08:00:26 +0900 Subject: [PATCH 05/15] Add nodeName template var and update doc (#6088) Signed-off-by: Ketian Xu Signed-off-by: Eduardo Apolinario Co-authored-by: Eduardo Apolinario --- .../configuring_logging_links_in_the_ui.md | 4 ++- flyteplugins/go/tasks/logs/logging_utils.go | 1 + .../go/tasks/logs/logging_utils_test.go | 33 +++++++++++++++---- .../tasks/pluginmachinery/tasklog/plugin.go | 1 + .../tasks/pluginmachinery/tasklog/template.go | 3 ++ .../pluginmachinery/tasklog/template_test.go | 8 +++-- 6 files changed, 41 insertions(+), 9 deletions(-) diff --git a/docs/user_guide/productionizing/configuring_logging_links_in_the_ui.md b/docs/user_guide/productionizing/configuring_logging_links_in_the_ui.md index 84c1c9d0cb..818ed476a0 100644 --- a/docs/user_guide/productionizing/configuring_logging_links_in_the_ui.md +++ b/docs/user_guide/productionizing/configuring_logging_links_in_the_ui.md @@ -40,7 +40,9 @@ The parameters can be used to generate a unique URL to the logs using a template * - ``{{ .logName }}`` - A deployment specific name where to expect the logs to be * - ``{{ .hostname }}`` - - The hostname where the pod is running and logs reside + - The value used to override the hostname the pod uses internally within its own network namespace (i.e., the pod's ``.spec.hostname``) + * - ``{{ .nodeName }}`` + - The hostname of the node where the pod is running and logs reside (i.e., the pod's ``.spec.nodeName``) * - ``{{ .podRFC3339StartTime }}`` - The pod creation time (in RFC3339 format, e.g. "2021-01-01T02:07:14Z", also conforming to ISO 8601) * - ``{{ .podRFC3339FinishTime }}`` diff --git a/flyteplugins/go/tasks/logs/logging_utils.go b/flyteplugins/go/tasks/logs/logging_utils.go index c237fc15c8..be1ab6438b 100644 --- a/flyteplugins/go/tasks/logs/logging_utils.go +++ b/flyteplugins/go/tasks/logs/logging_utils.go @@ -64,6 +64,7 @@ func GetLogsForContainerInPod(ctx context.Context, logPlugin tasklog.Plugin, tas ExtraTemplateVars: extraLogTemplateVars, TaskTemplate: taskTemplate, HostName: pod.Spec.Hostname, + NodeName: pod.Spec.NodeName, }, ) diff --git a/flyteplugins/go/tasks/logs/logging_utils_test.go b/flyteplugins/go/tasks/logs/logging_utils_test.go index e8c716e341..3b80ae8b6d 100644 --- a/flyteplugins/go/tasks/logs/logging_utils_test.go +++ b/flyteplugins/go/tasks/logs/logging_utils_test.go @@ -302,7 +302,7 @@ func TestGetLogsForContainerInPod_LegacyTemplate(t *testing.T) { MessageFormat: core.TaskLog_JSON, Name: "Stackdriver Logs my-Suffix", }, - }, "") + }, "", "") }) t.Run("StackDriver", func(t *testing.T) { @@ -315,11 +315,11 @@ func TestGetLogsForContainerInPod_LegacyTemplate(t *testing.T) { MessageFormat: core.TaskLog_JSON, Name: "Stackdriver Logs my-Suffix", }, - }, "") + }, "", "") }) } -func assertTestSucceeded(tb testing.TB, config *LogConfig, taskTemplate *core.TaskTemplate, expectedTaskLogs []*core.TaskLog, hostname string) { +func assertTestSucceeded(tb testing.TB, config *LogConfig, taskTemplate *core.TaskTemplate, expectedTaskLogs []*core.TaskLog, hostname string, nodeName string) { logPlugin, err := InitializeLogPlugins(config) assert.NoError(tb, err) @@ -335,6 +335,7 @@ func assertTestSucceeded(tb testing.TB, config *LogConfig, taskTemplate *core.Ta }, }, Hostname: hostname, + NodeName: nodeName, }, Status: v1.PodStatus{ ContainerStatuses: []v1.ContainerStatus{ @@ -382,7 +383,7 @@ func TestGetLogsForContainerInPod_Templates(t *testing.T) { MessageFormat: core.TaskLog_JSON, Name: "Internal my-Suffix", }, - }, "") + }, "", "") } func TestGetLogsForContainerInPodTemplates_Hostname(t *testing.T) { @@ -402,7 +403,27 @@ func TestGetLogsForContainerInPodTemplates_Hostname(t *testing.T) { MessageFormat: core.TaskLog_JSON, Name: "StackDriver my-Suffix", }, - }, "my-hostname") + }, "my-hostname", "") +} + +func TestGetLogsForContainerInPodTemplates_NodeName(t *testing.T) { + assertTestSucceeded(t, &LogConfig{ + Templates: []tasklog.TemplateLogPlugin{ + { + DisplayName: "MyLog", + TemplateURIs: []string{ + "{{ .nodeName }}/{{ .namespace }}/{{ .podName }}/{{ .containerName }}/{{ .containerId }}", + }, + MessageFormat: core.TaskLog_JSON, + }, + }, + }, nil, []*core.TaskLog{ + { + Uri: "ip-1-2-3-4/my-namespace/my-pod/ContainerName/ContainerID", + MessageFormat: core.TaskLog_JSON, + Name: "MyLog my-Suffix", + }, + }, "my-hostname", "ip-1-2-3-4") } func TestGetLogsForContainerInPod_Flyteinteractive(t *testing.T) { @@ -562,7 +583,7 @@ func TestGetLogsForContainerInPod_Flyteinteractive(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assertTestSucceeded(t, tt.config, tt.template, tt.expectedTaskLogs, "") + assertTestSucceeded(t, tt.config, tt.template, tt.expectedTaskLogs, "", "") }) } } diff --git a/flyteplugins/go/tasks/pluginmachinery/tasklog/plugin.go b/flyteplugins/go/tasks/pluginmachinery/tasklog/plugin.go index 143cf02e43..85a5961f0f 100644 --- a/flyteplugins/go/tasks/pluginmachinery/tasklog/plugin.go +++ b/flyteplugins/go/tasks/pluginmachinery/tasklog/plugin.go @@ -28,6 +28,7 @@ type TemplateVar struct { // log links. type Input struct { HostName string + NodeName string PodName string Namespace string ContainerName string diff --git a/flyteplugins/go/tasks/pluginmachinery/tasklog/template.go b/flyteplugins/go/tasks/pluginmachinery/tasklog/template.go index e8b7a4abed..c3f60268ed 100644 --- a/flyteplugins/go/tasks/pluginmachinery/tasklog/template.go +++ b/flyteplugins/go/tasks/pluginmachinery/tasklog/template.go @@ -27,6 +27,7 @@ type templateRegexes struct { ContainerName *regexp.Regexp ContainerID *regexp.Regexp Hostname *regexp.Regexp + NodeName *regexp.Regexp PodRFC3339StartTime *regexp.Regexp PodRFC3339FinishTime *regexp.Regexp PodUnixStartTime *regexp.Regexp @@ -52,6 +53,7 @@ func initDefaultRegexes() templateRegexes { MustCreateRegex("containerName"), MustCreateRegex("containerID"), MustCreateRegex("hostname"), + MustCreateRegex("nodeName"), MustCreateRegex("podRFC3339StartTime"), MustCreateRegex("podRFC3339FinishTime"), MustCreateRegex("podUnixStartTime"), @@ -105,6 +107,7 @@ func (input Input) templateVars() []TemplateVar { TemplateVar{defaultRegexes.ContainerName, input.ContainerName}, TemplateVar{defaultRegexes.ContainerID, containerID}, TemplateVar{defaultRegexes.Hostname, input.HostName}, + TemplateVar{defaultRegexes.NodeName, input.NodeName}, ) if input.TaskExecutionID != nil { taskExecutionIdentifier := input.TaskExecutionID.GetID() diff --git a/flyteplugins/go/tasks/pluginmachinery/tasklog/template_test.go b/flyteplugins/go/tasks/pluginmachinery/tasklog/template_test.go index 2e885732f8..da282b084a 100644 --- a/flyteplugins/go/tasks/pluginmachinery/tasklog/template_test.go +++ b/flyteplugins/go/tasks/pluginmachinery/tasklog/template_test.go @@ -63,6 +63,7 @@ func Test_Input_templateVars(t *testing.T) { } podBase := Input{ HostName: "my-host", + NodeName: "my-node-name", PodName: "my-pod", PodUID: "my-pod-uid", Namespace: "my-namespace", @@ -103,6 +104,7 @@ func Test_Input_templateVars(t *testing.T) { {defaultRegexes.ContainerName, "my-container"}, {defaultRegexes.ContainerID, "containerID"}, {defaultRegexes.Hostname, "my-host"}, + {defaultRegexes.NodeName, "my-node-name"}, {defaultRegexes.PodRFC3339StartTime, "1970-01-01T01:02:03+01:00"}, {defaultRegexes.PodRFC3339FinishTime, "1970-01-01T04:25:45+01:00"}, {defaultRegexes.PodUnixStartTime, "123"}, @@ -139,6 +141,7 @@ func Test_Input_templateVars(t *testing.T) { {defaultRegexes.ContainerName, ""}, {defaultRegexes.ContainerID, ""}, {defaultRegexes.Hostname, ""}, + {defaultRegexes.NodeName, ""}, {defaultRegexes.NodeID, "n0-0-n0"}, {defaultRegexes.GeneratedName, "generated-name"}, {defaultRegexes.TaskRetryAttempt, "1"}, @@ -327,12 +330,13 @@ func TestTemplateLogPlugin(t *testing.T) { { "ddog", TemplateLogPlugin{ - TemplateURIs: []TemplateURI{"https://app.datadoghq.com/logs?event&from_ts={{ .podUnixStartTime }}&live=true&query=pod_name%3A{{ .podName }}&to_ts={{ .podUnixFinishTime }}"}, + TemplateURIs: []TemplateURI{"https://app.datadoghq.com/logs?event&from_ts={{ .podUnixStartTime }}&live=true&query=pod_name%3A{{ .podName }}&to_ts={{ .podUnixFinishTime }}&host={{ .nodeName }}"}, MessageFormat: core.TaskLog_JSON, }, args{ input: Input{ HostName: "my-host", + NodeName: "ip-1-2-3-4", PodName: "my-pod", Namespace: "my-namespace", ContainerName: "my-container", @@ -347,7 +351,7 @@ func TestTemplateLogPlugin(t *testing.T) { Output{ TaskLogs: []*core.TaskLog{ { - Uri: "https://app.datadoghq.com/logs?event&from_ts=123&live=true&query=pod_name%3Amy-pod&to_ts=12345", + Uri: "https://app.datadoghq.com/logs?event&from_ts=123&live=true&query=pod_name%3Amy-pod&to_ts=12345&host=ip-1-2-3-4", MessageFormat: core.TaskLog_JSON, Name: "main_logs", }, From c06f188c10a51ab6827f624a28bc8467cd5ec6ab Mon Sep 17 00:00:00 2001 From: Christoph Paulik Date: Fri, 27 Dec 2024 00:12:33 +0100 Subject: [PATCH 06/15] Allow flytepropeller manager to have different resource request from flyte propeller (#5974) This can be good since the flytepropeller-manager pod does no work and needs next to no resources Signed-off-by: Christoph Paulik Signed-off-by: Eduardo Apolinario Co-authored-by: Eduardo Apolinario --- charts/flyte-core/README.md | 1 + charts/flyte-core/templates/propeller/deployment.yaml | 4 ++++ charts/flyte-core/values.yaml | 11 +++++++++++ docker/sandbox-bundled/manifests/complete-agent.yaml | 4 ++-- docker/sandbox-bundled/manifests/complete.yaml | 4 ++-- docker/sandbox-bundled/manifests/dev.yaml | 4 ++-- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/charts/flyte-core/README.md b/charts/flyte-core/README.md index a2fbd73276..e3f5dd2b6f 100644 --- a/charts/flyte-core/README.md +++ b/charts/flyte-core/README.md @@ -255,6 +255,7 @@ helm install gateway bitnami/contour -n flyte | flytepropeller.image.repository | string | `"cr.flyte.org/flyteorg/flytepropeller"` | Docker image for Flytepropeller deployment | | flytepropeller.image.tag | string | `"v1.14.1"` | | | flytepropeller.manager | bool | `false` | | +| flytepropeller.manager_resources | object | `{"resources":{"limits":{"cpu":"200m","ephemeral-storage":"100Mi","memory":"200Mi"},"requests":{"cpu":"10m","ephemeral-storage":"50Mi","memory":"100Mi"}}}` | If manager is set to true this can be used to give the flytepropeller-manager different resource requests than the sharded flyte propeller pods | | flytepropeller.nodeSelector | object | `{}` | nodeSelector for Flytepropeller deployment | | flytepropeller.podAnnotations | object | `{}` | Annotations for Flytepropeller pods | | flytepropeller.podEnv | object | `{}` | Additional Flytepropeller container environment variables | diff --git a/charts/flyte-core/templates/propeller/deployment.yaml b/charts/flyte-core/templates/propeller/deployment.yaml index 4308f2d6fa..c72db0e7b3 100644 --- a/charts/flyte-core/templates/propeller/deployment.yaml +++ b/charts/flyte-core/templates/propeller/deployment.yaml @@ -83,7 +83,11 @@ spec: {{- end }} ports: - containerPort: {{ index .Values.configmap.core.propeller "prof-port" }} + {{- if and (.Values.flytepropeller.manager) (.Values.flytepropeller.manager_resources) }} + resources: {{- toYaml .Values.flytepropeller.manager_resources.resources | nindent 10 }} + {{- else }} resources: {{- toYaml .Values.flytepropeller.resources | nindent 10 }} + {{- end }} volumeMounts: - name: config-volume mountPath: /etc/flyte/config diff --git a/charts/flyte-core/values.yaml b/charts/flyte-core/values.yaml index 4bc380c82d..8be6cb20e6 100755 --- a/charts/flyte-core/values.yaml +++ b/charts/flyte-core/values.yaml @@ -323,6 +323,17 @@ flytepropeller: cpu: 10m ephemeral-storage: 50Mi memory: 100Mi + # -- If manager is set to true this can be used to give the flytepropeller-manager different resource requests than the sharded flyte propeller pods + manager_resources: + resources: + limits: + cpu: 200m + ephemeral-storage: 100Mi + memory: 200Mi + requests: + cpu: 10m + ephemeral-storage: 50Mi + memory: 100Mi # -- Error reporting terminationMessagePolicy: FallbackToLogsOnError # -- Default regex string for searching configuration files diff --git a/docker/sandbox-bundled/manifests/complete-agent.yaml b/docker/sandbox-bundled/manifests/complete-agent.yaml index 6d2e9c4b4e..3a5a33b1d6 100644 --- a/docker/sandbox-bundled/manifests/complete-agent.yaml +++ b/docker/sandbox-bundled/manifests/complete-agent.yaml @@ -823,7 +823,7 @@ type: Opaque --- apiVersion: v1 data: - haSharedSecret: YUNORVNVRjBKVFpMTjVzZg== + haSharedSecret: ZVg2MDdXYnJyNXlYUWlLSA== proxyPassword: "" proxyUsername: "" kind: Secret @@ -1420,7 +1420,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: 89b23b61fb0b3e8423af547ebb08fefb82a79836f1eaaf90e838ebcb71bb2a1b + checksum/secret: 4d048d7850540d6862f070a28041c7c814d011e537872aecce2159789db2db79 labels: app: docker-registry release: flyte-sandbox diff --git a/docker/sandbox-bundled/manifests/complete.yaml b/docker/sandbox-bundled/manifests/complete.yaml index 9f8f7fe5cf..82cb2d9641 100644 --- a/docker/sandbox-bundled/manifests/complete.yaml +++ b/docker/sandbox-bundled/manifests/complete.yaml @@ -805,7 +805,7 @@ type: Opaque --- apiVersion: v1 data: - haSharedSecret: YmtheFJhUGp0WTh5dEo4Ug== + haSharedSecret: VXRnT3hJaE9CMEZldDJubg== proxyPassword: "" proxyUsername: "" kind: Secret @@ -1369,7 +1369,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: 249d45f57d99d60d9ba687a2b5451154fa1e5a1be8c5e399d769b7e0c73c5aaa + checksum/secret: 8a6224d331e9ccebb789367315d7f9677d9f4c7886640c8baeea547432cca5ad labels: app: docker-registry release: flyte-sandbox diff --git a/docker/sandbox-bundled/manifests/dev.yaml b/docker/sandbox-bundled/manifests/dev.yaml index 8800e6d9ad..7f7524f5ba 100644 --- a/docker/sandbox-bundled/manifests/dev.yaml +++ b/docker/sandbox-bundled/manifests/dev.yaml @@ -499,7 +499,7 @@ metadata: --- apiVersion: v1 data: - haSharedSecret: UU1hc3Z1dWJ0YVB4R01vZA== + haSharedSecret: bnFsU3VrQTFsRmd0azdvcQ== proxyPassword: "" proxyUsername: "" kind: Secret @@ -934,7 +934,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: ad2c03695a15547e840a4affe09ef070307393f9c4195ace08231ffaad4f7971 + checksum/secret: 492f9045abb64dc1e4f8fa90bb957960ea3ccd8d03b424a3a2fa2a83bfb87531 labels: app: docker-registry release: flyte-sandbox From 7f95782cfeba798229b8692e16da41a2254694bb Mon Sep 17 00:00:00 2001 From: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> Date: Fri, 27 Dec 2024 10:09:02 -0500 Subject: [PATCH 07/15] Unpin flytectl from single-binary tests (#6113) Signed-off-by: Eduardo Apolinario Co-authored-by: Eduardo Apolinario --- .github/workflows/single-binary.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/single-binary.yml b/.github/workflows/single-binary.yml index 2849c1eac4..1e31d703e4 100644 --- a/.github/workflows/single-binary.yml +++ b/.github/workflows/single-binary.yml @@ -159,8 +159,6 @@ jobs: with: python-version: "3.12" - uses: unionai/flytectl-setup-action@v0.0.3 - with: - version: '0.9.2' - name: Setup sandbox run: | mkdir -p ~/.flyte/sandbox From a796d24459572820af2ffff002adc34a2ade6ba2 Mon Sep 17 00:00:00 2001 From: Chun-Mao Lai <72752478+Mecoli1219@users.noreply.github.com> Date: Fri, 27 Dec 2024 11:32:11 -0800 Subject: [PATCH 08/15] Add new `sandbox-bundled-offloaded-functional-tests` for offloading literals unit test (#6111) * Enable offloading e2e test Signed-off-by: Mecoli1219 * Fix kube-config path Signed-off-by: Mecoli1219 * stop sandbox Signed-off-by: Mecoli1219 * change order Signed-off-by: Mecoli1219 * test Signed-off-by: Mecoli1219 * Update config.yaml Signed-off-by: Mecoli1219 --------- Signed-off-by: Mecoli1219 Signed-off-by: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> Co-authored-by: Eduardo Apolinario <653394+eapolinario@users.noreply.github.com> --- .github/workflows/single-binary.yml | 92 ++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/.github/workflows/single-binary.yml b/.github/workflows/single-binary.yml index 1e31d703e4..0423d2ec16 100644 --- a/.github/workflows/single-binary.yml +++ b/.github/workflows/single-binary.yml @@ -10,7 +10,7 @@ on: branches: - master - rc/* - - 'release-v**' + - "release-v**" workflow_dispatch: jobs: @@ -204,6 +204,96 @@ jobs: run: | make end2end_execute + sandbox-bundled-offloaded-functional-tests: + runs-on: ubuntu-latest + env: + FLYTESNACKS_PRIORITIES: "P0" + FLYTESNACKS_VERSION: "" + timeout-minutes: 60 + needs: [build-and-push-single-binary-image] + steps: + - name: Set latest Flytesnacks release + if: ${{ env.FLYTESNACKS_VERSION == '' }} + run: | + FLYTESNACKS_VERSION="$(curl --silent https://api.github.com/repos/flyteorg/flytesnacks/releases/latest | jq -r .tag_name)" + echo "FLYTESNACKS_VERSION=${FLYTESNACKS_VERSION}" >> ${GITHUB_ENV} + - name: Checkout + uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: single-binary-image + path: docker/sandbox-bundled/images/tar + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + with: + driver-opts: image=moby/buildkit:master + buildkitd-flags: "--allow-insecure-entitlement security.insecure" + - name: Build sandbox image for functional tests + uses: docker/build-push-action@v6 + with: + context: docker/sandbox-bundled + load: true + allow: "security.insecure" + tags: flyte-sandbox-bundled:local + # Without this, the GHA runner is under disk pressure and evicts all the pods. + # Buildx cache uses roughly 50% (7gb) of the GHA runner's disk (14gb). + - name: Prune Docker Buildx cache to reclaim storage + run: docker buildx prune --all --force + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.12" + - uses: unionai/flytectl-setup-action@v0.0.3 + - name: Setup sandbox + run: | + mkdir -p ~/.flyte/sandbox + cat << EOF > ~/.flyte/sandbox/config.yaml + propeller: + literal-offloading-config: + enabled: true + min-size-in-mb-for-offloading: 0.000001 + task_resources: + defaults: + cpu: "0" + memory: "0" + limits: + cpu: "0" + memory: "0" + EOF + flytectl demo start --image flyte-sandbox-bundled:local --imagePullPolicy Never + # By setting min-size-in-mb-for-offloading to 0.000001, we ensure that all tasks are offloaded. + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install uv + uv pip install --system flytekit flytekitplugins-deck-standard "numpy<2.0.0" pyarrow pandas + uv pip freeze + - name: Checkout flytesnacks + uses: actions/checkout@v4 + with: + repository: flyteorg/flytesnacks + path: flytesnacks + ref: ${{ env.FLYTESNACKS_VERSION }} + - name: Register specific tests + run: | + flytekit_version=$(pip show flytekit | grep -i version | awk '{ print $2 }') + while read -r line; + do + pyflyte -vv --config ./boilerplate/flyte/end2end/functional-test-config.yaml \ + register \ + --project flytesnacks \ + --domain development \ + --image cr.flyte.org/flyteorg/flytekit:py3.12-${flytekit_version} \ + --version ${{ env.FLYTESNACKS_VERSION }} \ + flytesnacks/$line; + done < flytesnacks/flyte_tests.txt + - name: Install Pytest + run: | + pip install pytest + - name: End2End + run: | + make end2end_execute + build-and-push-sandbox-bundled-image: if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} runs-on: ubuntu-latest From 4ce86a8ed108ac9c183af49cbbf55531d7e03d61 Mon Sep 17 00:00:00 2001 From: loselarry <166403105+loselarry@users.noreply.github.com> Date: Sat, 28 Dec 2024 04:11:22 +0800 Subject: [PATCH 09/15] chore: fix some function names in comment (#6122) Signed-off-by: loselarry --- flyteplugins/go/tasks/pluginmachinery/k8s/plugin.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flyteplugins/go/tasks/pluginmachinery/k8s/plugin.go b/flyteplugins/go/tasks/pluginmachinery/k8s/plugin.go index 8b2124e1cd..971f7de806 100644 --- a/flyteplugins/go/tasks/pluginmachinery/k8s/plugin.go +++ b/flyteplugins/go/tasks/pluginmachinery/k8s/plugin.go @@ -148,12 +148,12 @@ type UpdateResourceOperation struct { Options []client.UpdateOption } -// AbortBehavior that patches the default resource +// AbortBehaviorPatchDefaultResource that patches the default resource func AbortBehaviorPatchDefaultResource(patchOperation PatchResourceOperation, deleteOnErr bool) AbortBehavior { return AbortBehaviorPatch(patchOperation, deleteOnErr, nil) } -// AbortBehavior that patches the specified resource +// AbortBehaviorPatch that patches the specified resource func AbortBehaviorPatch(patchOperation PatchResourceOperation, deleteOnErr bool, resource client.Object) AbortBehavior { return AbortBehavior{ Resource: resource, @@ -162,12 +162,12 @@ func AbortBehaviorPatch(patchOperation PatchResourceOperation, deleteOnErr bool, } } -// AbortBehavior that updates the default resource +// AbortBehaviorUpdateDefaultResource that updates the default resource func AbortBehaviorUpdateDefaultResource(updateOperation UpdateResourceOperation, deleteOnErr bool) AbortBehavior { return AbortBehaviorUpdate(updateOperation, deleteOnErr, nil) } -// AbortBehavior that updates the specified resource +// AbortBehaviorUpdate that updates the specified resource func AbortBehaviorUpdate(updateOperation UpdateResourceOperation, deleteOnErr bool, resource client.Object) AbortBehavior { return AbortBehavior{ Resource: resource, @@ -176,12 +176,12 @@ func AbortBehaviorUpdate(updateOperation UpdateResourceOperation, deleteOnErr bo } } -// AbortBehavior that deletes the default resource +// AbortBehaviorDeleteDefaultResource that deletes the default resource func AbortBehaviorDeleteDefaultResource() AbortBehavior { return AbortBehaviorDelete(nil) } -// AbortBehavior that deletes the specified resource +// AbortBehaviorDelete that deletes the specified resource func AbortBehaviorDelete(resource client.Object) AbortBehavior { return AbortBehavior{ Resource: resource, From 61838b47aa0eb97603842bbd875c2953d444b596 Mon Sep 17 00:00:00 2001 From: Alex Wu <66259759+popojk@users.noreply.github.com> Date: Sat, 28 Dec 2024 04:18:19 +0800 Subject: [PATCH 10/15] Flyteadmin digest comparison should rely on database semantics (#6058) * to TaskManager CreateTask in transactional way Signed-off-by: Alex Wu * amend TaskRepo Create method to create task before description to prevent TaskManager CreateTask method Task not found isue Signed-off-by: Alex Wu * add unit test Signed-off-by: Alex Wu * fix lint error Signed-off-by: Alex Wu --------- Signed-off-by: Alex Wu --- flyteadmin/pkg/manager/impl/task_manager.go | 38 +++++++----- .../pkg/manager/impl/task_manager_test.go | 61 +++++++++++++++++++ .../pkg/repositories/gormimpl/task_repo.go | 4 +- 3 files changed, 85 insertions(+), 18 deletions(-) diff --git a/flyteadmin/pkg/manager/impl/task_manager.go b/flyteadmin/pkg/manager/impl/task_manager.go index 7d903e98fb..c5735fe406 100644 --- a/flyteadmin/pkg/manager/impl/task_manager.go +++ b/flyteadmin/pkg/manager/impl/task_manager.go @@ -88,19 +88,7 @@ func (t *TaskManager) CreateTask( logger.Errorf(ctx, "failed to compute task digest with err %v", err) return nil, err } - // See if a task exists and confirm whether it's an identical task or one that with a separate definition. - existingTaskModel, err := util.GetTaskModel(ctx, t.db, request.GetSpec().GetTemplate().GetId()) - if err == nil { - if bytes.Equal(taskDigest, existingTaskModel.Digest) { - return nil, errors.NewTaskExistsIdenticalStructureError(ctx, request) - } - existingTask, transformerErr := transformers.FromTaskModel(*existingTaskModel) - if transformerErr != nil { - logger.Errorf(ctx, "failed to transform task from task model") - return nil, transformerErr - } - return nil, errors.NewTaskExistsDifferentStructureError(ctx, request, existingTask.GetClosure().GetCompiledTask(), compiledTask) - } + // Create Task in DB taskModel, err := transformers.CreateTaskModel(finalizedRequest, &admin.TaskClosure{ CompiledTask: compiledTask, CreatedAt: createdAt, @@ -110,7 +98,6 @@ func (t *TaskManager) CreateTask( "Failed to transform task model [%+v] with err: %v", finalizedRequest, err) return nil, err } - descriptionModel, err := transformers.CreateDescriptionEntityModel(request.GetSpec().GetDescription(), request.GetId()) if err != nil { logger.Errorf(ctx, @@ -122,8 +109,27 @@ func (t *TaskManager) CreateTask( } err = t.db.TaskRepo().Create(ctx, taskModel, descriptionModel) if err != nil { - logger.Debugf(ctx, "Failed to create task model with id [%+v] with err %v", request.GetId(), err) - return nil, err + // See if an identical task already exists by checking the error code + flyteErr, ok := err.(errors.FlyteAdminError) + if !ok || flyteErr.Code() != codes.AlreadyExists { + logger.Errorf(ctx, "Failed to create task model with id [%+v] with err %v", request.GetId(), err) + return nil, err + } + // An identical task already exists. Fetch the existing task to verify if it has a different digest + existingTaskModel, fetchErr := util.GetTaskModel(ctx, t.db, request.GetSpec().GetTemplate().GetId()) + if fetchErr != nil { + logger.Errorf(ctx, "Failed to fetch existing task model for id [%+v] with err %v", request.GetId(), fetchErr) + return nil, fetchErr + } + if bytes.Equal(taskDigest, existingTaskModel.Digest) { + return nil, errors.NewTaskExistsIdenticalStructureError(ctx, request) + } + existingTask, transformerErr := transformers.FromTaskModel(*existingTaskModel) + if transformerErr != nil { + logger.Errorf(ctx, "Failed to transform task from task model for id [%+v]", request.GetId()) + return nil, transformerErr + } + return nil, errors.NewTaskExistsDifferentStructureError(ctx, request, existingTask.GetClosure().GetCompiledTask(), compiledTask) } t.metrics.ClosureSizeBytes.Observe(float64(len(taskModel.Closure))) if finalizedRequest.GetSpec().GetTemplate().GetMetadata() != nil { diff --git a/flyteadmin/pkg/manager/impl/task_manager_test.go b/flyteadmin/pkg/manager/impl/task_manager_test.go index 1301444ceb..50fc2c3234 100644 --- a/flyteadmin/pkg/manager/impl/task_manager_test.go +++ b/flyteadmin/pkg/manager/impl/task_manager_test.go @@ -99,6 +99,67 @@ func TestCreateTask(t *testing.T) { assert.NotNil(t, response) } +func TestCreateTask_DuplicateTaskRegistration(t *testing.T) { + mockRepository := getMockTaskRepository() + mockRepository.TaskRepo().(*repositoryMocks.MockTaskRepo).SetGetCallback( + func(input interfaces.Identifier) (models.Task, error) { + return models.Task{ + TaskKey: models.TaskKey{ + Project: taskIdentifier.GetProject(), + Domain: taskIdentifier.GetDomain(), + Name: taskIdentifier.GetName(), + Version: taskIdentifier.GetVersion(), + }, + Digest: []byte{ + 0xbf, 0x79, 0x61, 0x1c, 0xf5, 0xc1, 0xfb, 0x4c, 0xf8, 0xf4, 0xc4, 0x53, 0x5f, 0x8f, 0x73, 0xe2, 0x26, 0x5a, + 0x18, 0x4a, 0xb7, 0x66, 0x98, 0x3c, 0xab, 0x2, 0x6c, 0x9, 0x9b, 0x90, 0xec, 0x8f}, + }, nil + }) + mockRepository.TaskRepo().(*repositoryMocks.MockTaskRepo).SetCreateCallback(func(input models.Task, descriptionEntity *models.DescriptionEntity) error { + return adminErrors.NewFlyteAdminErrorf(codes.AlreadyExists, "task already exists") + }) + taskManager := NewTaskManager(mockRepository, getMockConfigForTaskTest(), getMockTaskCompiler(), + mockScope.NewTestScope()) + request := testutils.GetValidTaskRequest() + _, err := taskManager.CreateTask(context.Background(), request) + assert.Error(t, err) + flyteErr, ok := err.(adminErrors.FlyteAdminError) + assert.True(t, ok, "Error should be of type FlyteAdminError") + assert.Equal(t, codes.AlreadyExists, flyteErr.Code(), "Error code should be AlreadyExists") + assert.Contains(t, flyteErr.Error(), "task with identical structure already exists") + differentTemplate := &core.TaskTemplate{ + Id: &core.Identifier{ + ResourceType: core.ResourceType_TASK, + Project: "project", + Domain: "domain", + Name: "name", + Version: "version", + }, + Type: "type", + Metadata: &core.TaskMetadata{ + Runtime: &core.RuntimeMetadata{ + Version: "runtime version 2", + }, + }, + Interface: &core.TypedInterface{}, + Target: &core.TaskTemplate_Container{ + Container: &core.Container{ + Image: "image", + Command: []string{ + "command", + }, + }, + }, + } + request.Spec.Template = differentTemplate + _, err = taskManager.CreateTask(context.Background(), request) + assert.Error(t, err) + flyteErr, ok = err.(adminErrors.FlyteAdminError) + assert.True(t, ok, "Error should be of type FlyteAdminError") + assert.Equal(t, codes.InvalidArgument, flyteErr.Code(), "Error code should be InvalidArgument") + assert.Contains(t, flyteErr.Error(), "name task with different structure already exists.") +} + func TestCreateTask_ValidationError(t *testing.T) { mockRepository := getMockTaskRepository() taskManager := NewTaskManager(mockRepository, getMockConfigForTaskTest(), getMockTaskCompiler(), diff --git a/flyteadmin/pkg/repositories/gormimpl/task_repo.go b/flyteadmin/pkg/repositories/gormimpl/task_repo.go index 1b42756b7a..3f99172224 100644 --- a/flyteadmin/pkg/repositories/gormimpl/task_repo.go +++ b/flyteadmin/pkg/repositories/gormimpl/task_repo.go @@ -30,12 +30,12 @@ func (r *TaskRepo) Create(ctx context.Context, input models.Task, descriptionEnt } return nil } - tx := r.db.WithContext(ctx).Omit("id").Create(descriptionEntity) + tx := r.db.WithContext(ctx).Omit("id").Create(&input) if tx.Error != nil { return r.errorTransformer.ToFlyteAdminError(tx.Error) } - tx = r.db.WithContext(ctx).Omit("id").Create(&input) + tx = r.db.WithContext(ctx).Omit("id").Create(descriptionEntity) if tx.Error != nil { return r.errorTransformer.ToFlyteAdminError(tx.Error) } From fd9a3780618da3d08843abf7843011dc89d85a54 Mon Sep 17 00:00:00 2001 From: Katrina Rogan Date: Thu, 2 Jan 2025 15:50:06 +0100 Subject: [PATCH 11/15] Upgrade golang.org/x/crypto lib to address vulnerability (#6133) Signed-off-by: Katrina Rogan --- boilerplate/flyte/golang_support_tools/go.mod | 10 +++++----- boilerplate/flyte/golang_support_tools/go.sum | 20 +++++++++---------- datacatalog/go.mod | 10 +++++----- datacatalog/go.sum | 20 +++++++++---------- flyteadmin/go.mod | 10 +++++----- flyteadmin/go.sum | 20 +++++++++---------- flytecopilot/go.mod | 10 +++++----- flytecopilot/go.sum | 20 +++++++++---------- flytectl/go.mod | 10 +++++----- flytectl/go.sum | 20 +++++++++---------- flyteidl/go.mod | 10 +++++----- flyteidl/go.sum | 20 +++++++++---------- flyteplugins/go.mod | 10 +++++----- flyteplugins/go.sum | 20 +++++++++---------- flytepropeller/go.mod | 10 +++++----- flytepropeller/go.sum | 20 +++++++++---------- flytestdlib/go.mod | 10 +++++----- flytestdlib/go.sum | 20 +++++++++---------- go.mod | 10 +++++----- go.sum | 20 +++++++++---------- 20 files changed, 150 insertions(+), 150 deletions(-) diff --git a/boilerplate/flyte/golang_support_tools/go.mod b/boilerplate/flyte/golang_support_tools/go.mod index 469b42d079..0559544348 100644 --- a/boilerplate/flyte/golang_support_tools/go.mod +++ b/boilerplate/flyte/golang_support_tools/go.mod @@ -242,16 +242,16 @@ require ( go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.25.0 // indirect - golang.org/x/crypto v0.27.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect google.golang.org/api v0.196.0 // indirect diff --git a/boilerplate/flyte/golang_support_tools/go.sum b/boilerplate/flyte/golang_support_tools/go.sum index fc017b6f44..74bc3c5256 100644 --- a/boilerplate/flyte/golang_support_tools/go.sum +++ b/boilerplate/flyte/golang_support_tools/go.sum @@ -632,8 +632,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= @@ -691,8 +691,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -720,16 +720,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -738,8 +738,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/datacatalog/go.mod b/datacatalog/go.mod index 53fc2ce90f..ef228557a0 100644 --- a/datacatalog/go.mod +++ b/datacatalog/go.mod @@ -117,14 +117,14 @@ require ( go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/datacatalog/go.sum b/datacatalog/go.sum index b4c75df142..7cef31b6b1 100644 --- a/datacatalog/go.sum +++ b/datacatalog/go.sum @@ -425,8 +425,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -520,8 +520,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -564,12 +564,12 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -578,8 +578,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/flyteadmin/go.mod b/flyteadmin/go.mod index 82e2189f34..b33f04b857 100644 --- a/flyteadmin/go.mod +++ b/flyteadmin/go.mod @@ -53,7 +53,7 @@ require ( go.opentelemetry.io/otel v1.24.0 golang.org/x/net v0.27.0 golang.org/x/oauth2 v0.18.0 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.10.0 golang.org/x/time v0.5.0 google.golang.org/api v0.155.0 google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 @@ -195,11 +195,11 @@ require ( go.opentelemetry.io/proto/otlp v1.1.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect diff --git a/flyteadmin/go.sum b/flyteadmin/go.sum index afd775c3ba..b2af14d8cf 100644 --- a/flyteadmin/go.sum +++ b/flyteadmin/go.sum @@ -1431,8 +1431,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1566,8 +1566,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1657,8 +1657,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1666,8 +1666,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1679,8 +1679,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/flytecopilot/go.mod b/flytecopilot/go.mod index a8071b5a8a..4185d2af24 100644 --- a/flytecopilot/go.mod +++ b/flytecopilot/go.mod @@ -102,14 +102,14 @@ require ( go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/flytecopilot/go.sum b/flytecopilot/go.sum index 8f33fe7002..2f7a03f409 100644 --- a/flytecopilot/go.sum +++ b/flytecopilot/go.sum @@ -395,8 +395,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -490,8 +490,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -534,12 +534,12 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -548,8 +548,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/flytectl/go.mod b/flytectl/go.mod index a8b0fe8bb2..3876de9fc4 100644 --- a/flytectl/go.mod +++ b/flytectl/go.mod @@ -36,7 +36,7 @@ require ( github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 github.com/zalando/go-keyring v0.1.1 golang.org/x/oauth2 v0.18.0 - golang.org/x/text v0.16.0 + golang.org/x/text v0.21.0 google.golang.org/grpc v1.62.1 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 @@ -168,12 +168,12 @@ require ( go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/flytectl/go.sum b/flytectl/go.sum index 9f81c0ec9d..49ac308bf0 100644 --- a/flytectl/go.sum +++ b/flytectl/go.sum @@ -531,8 +531,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -626,8 +626,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -675,12 +675,12 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -689,8 +689,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/flyteidl/go.mod b/flyteidl/go.mod index 6653ce5a87..d2bdfe144d 100644 --- a/flyteidl/go.mod +++ b/flyteidl/go.mod @@ -97,12 +97,12 @@ require ( go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/flyteidl/go.sum b/flyteidl/go.sum index b398d5d02f..902dab4b4d 100644 --- a/flyteidl/go.sum +++ b/flyteidl/go.sum @@ -283,8 +283,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= @@ -316,8 +316,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -333,18 +333,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/flyteplugins/go.mod b/flyteplugins/go.mod index 11962b93c9..0517890f35 100644 --- a/flyteplugins/go.mod +++ b/flyteplugins/go.mod @@ -131,11 +131,11 @@ require ( go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect diff --git a/flyteplugins/go.sum b/flyteplugins/go.sum index 18242a8638..58612ea7c8 100644 --- a/flyteplugins/go.sum +++ b/flyteplugins/go.sum @@ -430,8 +430,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -525,8 +525,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -570,12 +570,12 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -584,8 +584,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/flytepropeller/go.mod b/flytepropeller/go.mod index c129312e44..766d3271c8 100644 --- a/flytepropeller/go.mod +++ b/flytepropeller/go.mod @@ -34,7 +34,7 @@ require ( go.opentelemetry.io/otel v1.24.0 go.opentelemetry.io/otel/trace v1.24.0 golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.10.0 golang.org/x/time v0.5.0 google.golang.org/grpc v1.62.1 google.golang.org/protobuf v1.34.1 @@ -141,12 +141,12 @@ require ( go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/flytepropeller/go.sum b/flytepropeller/go.sum index 63c498dc77..f41ac7a8da 100644 --- a/flytepropeller/go.sum +++ b/flytepropeller/go.sum @@ -480,8 +480,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -577,8 +577,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -628,12 +628,12 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -642,8 +642,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/flytestdlib/go.mod b/flytestdlib/go.mod index 91a9588d9d..ff21c6c8d6 100644 --- a/flytestdlib/go.mod +++ b/flytestdlib/go.mod @@ -126,15 +126,15 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect diff --git a/flytestdlib/go.sum b/flytestdlib/go.sum index 5af566903d..08bf8c48f0 100644 --- a/flytestdlib/go.sum +++ b/flytestdlib/go.sum @@ -429,8 +429,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -526,8 +526,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -570,12 +570,12 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -584,8 +584,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/go.mod b/go.mod index 48cf680956..37e8aa4301 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/prometheus/client_golang v1.19.1 github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.10.0 gorm.io/driver/postgres v1.5.3 sigs.k8s.io/controller-runtime v0.16.3 ) @@ -197,13 +197,13 @@ require ( go.opentelemetry.io/proto/otlp v1.1.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index d61dd5d2d9..d6f059adf6 100644 --- a/go.sum +++ b/go.sum @@ -1470,8 +1470,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1605,8 +1605,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1696,8 +1696,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1705,8 +1705,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1718,8 +1718,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 27c9edde18c67b51a6ea22441ff6a96c5a9482f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Torrentsgener=C3=B3s?= Date: Sat, 4 Jan 2025 04:22:04 +0100 Subject: [PATCH 12/15] chore: using domain-qualified finalizers (#6023) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: using domain-qualified finalizers Signed-off-by: Roger Torrentsgenerós * test: adding test, fixing others Signed-off-by: Roger Torrentsgenerós * chore: use flyte.org/finalizer instead Signed-off-by: Roger Torrentsgenerós --------- Signed-off-by: Roger Torrentsgenerós --- flyteadmin/go.mod | 4 ++ flyteadmin/go.sum | 6 ++ .../workflowengine/impl/prepare_execution.go | 4 +- .../impl/prepare_execution_test.go | 3 +- .../go/tasks/plugins/array/k8s/subtask.go | 42 ++++++----- flytepropeller/pkg/controller/controller.go | 5 ++ flytepropeller/pkg/controller/finalizer.go | 36 ---------- .../pkg/controller/finalizer_test.go | 70 ------------------- flytepropeller/pkg/controller/handler.go | 17 +++-- flytepropeller/pkg/controller/handler_test.go | 35 +++++----- .../nodes/task/k8s/plugin_manager.go | 39 +++++++---- .../nodes/task/k8s/plugin_manager_test.go | 30 ++++++-- go.mod | 1 - 13 files changed, 124 insertions(+), 168 deletions(-) delete mode 100644 flytepropeller/pkg/controller/finalizer.go delete mode 100644 flytepropeller/pkg/controller/finalizer_test.go diff --git a/flyteadmin/go.mod b/flyteadmin/go.mod index b33f04b857..10fdaccff7 100644 --- a/flyteadmin/go.mod +++ b/flyteadmin/go.mod @@ -108,6 +108,7 @@ require ( github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-redis/redis v6.15.7+incompatible // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/go-test/deep v1.0.7 // indirect github.com/goccy/go-json v0.10.2 // indirect @@ -155,6 +156,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/ncw/swift v1.0.53 // indirect + github.com/nxadm/tail v1.4.11 // indirect github.com/ory/go-acc v0.2.6 // indirect github.com/ory/go-convenience v0.1.0 // indirect github.com/ory/viper v1.7.5 // indirect @@ -201,6 +203,7 @@ require ( golang.org/x/term v0.27.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect @@ -214,6 +217,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.28.4 // indirect + k8s.io/component-base v0.28.4 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/flyteadmin/go.sum b/flyteadmin/go.sum index b2af14d8cf..8b48761ab9 100644 --- a/flyteadmin/go.sum +++ b/flyteadmin/go.sum @@ -340,6 +340,8 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U= +github.com/go-redis/redis v6.15.7+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -1013,6 +1015,8 @@ github.com/ncw/swift v1.0.53/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oleiade/reflections v1.0.0/go.mod h1:RbATFBbKYkVdqmSFtx13Bb/tVhR0lgOBXunWTZKeL4w= github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= @@ -1024,6 +1028,7 @@ github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -1971,6 +1976,7 @@ gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76 gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/validator.v2 v2.0.0-20180514200540-135c24b11c19/go.mod h1:o4V0GXN9/CAmCsvJ0oXYZvrZOe7syiDZSN1GWGZTGzc= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/flyteadmin/pkg/workflowengine/impl/prepare_execution.go b/flyteadmin/pkg/workflowengine/impl/prepare_execution.go index 70afadbd7b..7432a08ea6 100644 --- a/flyteadmin/pkg/workflowengine/impl/prepare_execution.go +++ b/flyteadmin/pkg/workflowengine/impl/prepare_execution.go @@ -4,12 +4,14 @@ import ( "github.com/golang/protobuf/proto" "google.golang.org/grpc/codes" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/flyteorg/flyte/flyteadmin/pkg/errors" "github.com/flyteorg/flyte/flyteadmin/pkg/workflowengine/interfaces" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" "github.com/flyteorg/flyte/flytepropeller/pkg/apis/flyteworkflow/v1alpha1" + "github.com/flyteorg/flyte/flytepropeller/pkg/controller" ) func addMapValues(overrides map[string]string, defaultValues map[string]string) map[string]string { @@ -130,7 +132,7 @@ func PrepareFlyteWorkflow(data interfaces.ExecutionData, flyteWorkflow *v1alpha1 flyteWorkflow.AcceptedAt = &acceptAtWrapper // Add finalizer - flyteWorkflow.Finalizers = append(flyteWorkflow.Finalizers, "flyte-finalizer") + _ = controllerutil.AddFinalizer(flyteWorkflow, controller.Finalizer) // add permissions from auth and security context. Adding permissions from auth would be removed once all clients // have migrated over to security context diff --git a/flyteadmin/pkg/workflowengine/impl/prepare_execution_test.go b/flyteadmin/pkg/workflowengine/impl/prepare_execution_test.go index 58d5fa3934..2a6ff2008c 100644 --- a/flyteadmin/pkg/workflowengine/impl/prepare_execution_test.go +++ b/flyteadmin/pkg/workflowengine/impl/prepare_execution_test.go @@ -14,6 +14,7 @@ import ( "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" "github.com/flyteorg/flyte/flytepropeller/pkg/apis/flyteworkflow/v1alpha1" + "github.com/flyteorg/flyte/flytepropeller/pkg/controller" ) const testRole = "role" @@ -254,5 +255,5 @@ func TestPrepareFlyteWorkflow(t *testing.T) { OutputLocationPrefix: "s3://bucket/key", }, }) - assert.Equal(t, flyteWorkflow.Finalizers, []string{"flyte-finalizer"}) + assert.Equal(t, flyteWorkflow.Finalizers, []string{controller.Finalizer}) } diff --git a/flyteplugins/go/tasks/plugins/array/k8s/subtask.go b/flyteplugins/go/tasks/plugins/array/k8s/subtask.go index cb1a2c0b5f..bdc1c716b7 100644 --- a/flyteplugins/go/tasks/plugins/array/k8s/subtask.go +++ b/flyteplugins/go/tasks/plugins/array/k8s/subtask.go @@ -13,6 +13,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" k8stypes "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/flyteorg/flyte/flyteplugins/go/tasks/errors" pluginsCore "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/core" @@ -30,8 +31,11 @@ const ( ErrBuildPodTemplate stdErrors.ErrorCode = "POD_TEMPLATE_FAILED" ErrReplaceCmdTemplate stdErrors.ErrorCode = "CMD_TEMPLATE_FAILED" FlyteK8sArrayIndexVarName string = "FLYTE_K8S_ARRAY_INDEX" - finalizer string = "flyte/array" - JobIndexVarName string = "BATCH_JOB_ARRAY_INDEX_VAR_NAME" + finalizer string = "flyte.org/finalizer-array" + // Old non-domain-qualified finalizer for backwards compatibility + // This should eventually be removed + oldFinalizer string = "flyte/array" + JobIndexVarName string = "BATCH_JOB_ARRAY_INDEX_VAR_NAME" ) var ( @@ -69,8 +73,7 @@ func addMetadata(stCtx SubTaskExecutionContext, cfg *Config, k8sPluginCfg *confi } if k8sPluginCfg.InjectFinalizer { - f := append(pod.GetFinalizers(), finalizer) - pod.SetFinalizers(f) + _ = controllerutil.AddFinalizer(pod, finalizer) } if len(cfg.DefaultScheduler) > 0 { @@ -134,7 +137,7 @@ func abortSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Confi } if err != nil && !isK8sObjectNotExists(err) { - logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v/%v. Error: %v", + logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v/%v. Error: %v", resourceToFinalize.GetNamespace(), resourceToFinalize.GetName(), err) return err } @@ -142,17 +145,20 @@ func abortSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Confi return nil } -// clearFinalizers removes finalizers (if they exist) from the k8s resource -func clearFinalizers(ctx context.Context, o client.Object, kubeClient pluginsCore.KubeClient) error { - if len(o.GetFinalizers()) > 0 { - o.SetFinalizers([]string{}) +// clearFinalizer removes the Flyte finalizer (if it exists) from the k8s resource +func clearFinalizer(ctx context.Context, o client.Object, kubeClient pluginsCore.KubeClient) error { + // Checking for the old finalizer too for backwards compatibility. This should eventually be removed + // Go does short-circuiting so we have to make sure both are removed + finalizerRemoved := controllerutil.RemoveFinalizer(o, finalizer) + oldFinalizerRemoved := controllerutil.RemoveFinalizer(o, oldFinalizer) + if finalizerRemoved || oldFinalizerRemoved { err := kubeClient.GetClient().Update(ctx, o) if err != nil && !isK8sObjectNotExists(err) { - logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v/%v. Error: %v", o.GetNamespace(), o.GetName(), err) + logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v/%v. Error: %v", o.GetNamespace(), o.GetName(), err) return err } } else { - logger.Debugf(ctx, "Finalizers are already empty for Resource with name: %v/%v", o.GetNamespace(), o.GetName()) + logger.Debugf(ctx, "Finalizer is already cleared for Resource with name: %v/%v", o.GetNamespace(), o.GetName()) } return nil } @@ -211,7 +217,7 @@ func launchSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Conf } // finalizeSubtask performs operations to complete the k8s pod defined by the SubTaskExecutionContext -// and Config. These may include removing finalizers and deleting the k8s resource. +// and Config. These may include removing finalizer and deleting the k8s resource. func finalizeSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Config, kubeClient pluginsCore.KubeClient) error { errs := stdErrors.ErrorCollection{} var pod *v1.Pod @@ -231,10 +237,10 @@ func finalizeSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Co nsName = k8stypes.NamespacedName{Namespace: pod.GetNamespace(), Name: pod.GetName()} } - // In InjectFinalizer is on, it means we may have added the finalizers when we launched this resource. Attempt to - // clear them to allow the object to be deleted/garbage collected. If InjectFinalizer was turned on (through config) + // In InjectFinalizer is on, it means we may have added the finalizer when we launched this resource. Attempt to + // clear it to allow the object to be deleted/garbage collected. If InjectFinalizer was turned on (through config) // after the resource was created, we will not find any finalizers to clear and the object may have already been - // deleted at this point. Therefore, account for these cases and do not consider them errors. + // deleted at this point. Therefore, account for these cases and do not consider the errors. if k8sPluginCfg.InjectFinalizer { // Attempt to get resource from informer cache, if not found, retrieve it from API server. if err := kubeClient.GetClient().Get(ctx, nsName, pod); err != nil { @@ -250,7 +256,7 @@ func finalizeSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Co // This must happen after sending admin event. It's safe against partial failures because if the event failed, we will // simply retry in the next round. If the event succeeded but this failed, we will try again the next round to send // the same event (idempotent) and then come here again... - err := clearFinalizers(ctx, pod, kubeClient) + err := clearFinalizer(ctx, pod, kubeClient) if err != nil { errs.Append(err) } @@ -308,10 +314,10 @@ func getSubtaskPhaseInfo(ctx context.Context, stCtx SubTaskExecutionContext, cfg return pluginsCore.PhaseInfoUndefined, err } - if !phaseInfo.Phase().IsTerminal() && o.GetDeletionTimestamp() != nil { + if !phaseInfo.Phase().IsTerminal() && !o.GetDeletionTimestamp().IsZero() { // If the object has been deleted, that is, it has a deletion timestamp, but is not in a terminal state, we should // mark the task as a retryable failure. We've seen this happen when a kubelet disappears - all pods running on - // the node are marked with a deletionTimestamp, but our finalizers prevent the pod from being deleted. + // the node are marked with a deletionTimestamp, but our finalizer prevents the pod from being deleted. // This can also happen when a user deletes a Pod directly. failureReason := fmt.Sprintf("object [%s] terminated in the background, manually", nsName.String()) return pluginsCore.PhaseInfoSystemRetryableFailure("UnexpectedObjectDeletion", failureReason, nil), nil diff --git a/flytepropeller/pkg/controller/controller.go b/flytepropeller/pkg/controller/controller.go index 8d733c33a3..9cef800125 100644 --- a/flytepropeller/pkg/controller/controller.go +++ b/flytepropeller/pkg/controller/controller.go @@ -61,6 +61,11 @@ import ( ) const ( + // Finalizer is the global and domain-qualified Flyte finalizer + Finalizer = "flyte.org/finalizer" + // OldFinalizer is the old non-domain-qualified finalizer, kept for backwards compatibility + // This should eventually be removed + OldFinalizer = "flyte-finalizer" resourceLevelMonitorCycleDuration = 5 * time.Second missing = "missing" podDefaultNamespace = "flyte" diff --git a/flytepropeller/pkg/controller/finalizer.go b/flytepropeller/pkg/controller/finalizer.go deleted file mode 100644 index f1a8ba8ebd..0000000000 --- a/flytepropeller/pkg/controller/finalizer.go +++ /dev/null @@ -1,36 +0,0 @@ -package controller - -import v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -const FinalizerKey = "flyte-finalizer" - -// NOTE: Some of these APIs are exclusive and do not compare the actual values of the finalizers. -// the intention of this module is to set only one opaque finalizer at a time. If you want to set multiple (not common) -// finalizers, use this module carefully and at your own risk! - -// Sets a new finalizer in case the finalizer is empty -func SetFinalizerIfEmpty(meta v1.Object, finalizer string) { - if !HasFinalizer(meta) { - meta.SetFinalizers([]string{finalizer}) - } -} - -// Check if the deletion timestamp is set, this is set automatically when an object is deleted -func IsDeleted(meta v1.Object) bool { - return meta.GetDeletionTimestamp() != nil -} - -// Reset all the finalizers on the object -func ResetFinalizers(meta v1.Object) { - meta.SetFinalizers([]string{}) -} - -// Currently we only compare the lengths of finalizers. If you add finalizers directly these API;'s will not work -func FinalizersIdentical(o1 v1.Object, o2 v1.Object) bool { - return len(o1.GetFinalizers()) == len(o2.GetFinalizers()) -} - -// Check if any finalizer is set -func HasFinalizer(meta v1.Object) bool { - return len(meta.GetFinalizers()) != 0 -} diff --git a/flytepropeller/pkg/controller/finalizer_test.go b/flytepropeller/pkg/controller/finalizer_test.go deleted file mode 100644 index 05401806d6..0000000000 --- a/flytepropeller/pkg/controller/finalizer_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package controller - -import ( - "testing" - - "github.com/stretchr/testify/assert" - v1 "k8s.io/api/batch/v1" - v12 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestFinalizersIdentical(t *testing.T) { - noFinalizer := &v1.Job{} - withFinalizer := &v1.Job{} - withFinalizer.SetFinalizers([]string{"t1"}) - - assert.True(t, FinalizersIdentical(noFinalizer, noFinalizer)) - assert.True(t, FinalizersIdentical(withFinalizer, withFinalizer)) - assert.False(t, FinalizersIdentical(noFinalizer, withFinalizer)) - withMultipleFinalizers := &v1.Job{} - withMultipleFinalizers.SetFinalizers([]string{"f1", "f2"}) - assert.False(t, FinalizersIdentical(withMultipleFinalizers, withFinalizer)) - - withDiffFinalizer := &v1.Job{} - withDiffFinalizer.SetFinalizers([]string{"f1"}) - assert.True(t, FinalizersIdentical(withFinalizer, withDiffFinalizer)) -} - -func TestIsDeleted(t *testing.T) { - noTermTS := &v1.Job{} - termedTS := &v1.Job{} - n := v12.Now() - termedTS.SetDeletionTimestamp(&n) - - assert.True(t, IsDeleted(termedTS)) - assert.False(t, IsDeleted(noTermTS)) -} - -func TestHasFinalizer(t *testing.T) { - noFinalizer := &v1.Job{} - withFinalizer := &v1.Job{} - withFinalizer.SetFinalizers([]string{"t1"}) - - assert.False(t, HasFinalizer(noFinalizer)) - assert.True(t, HasFinalizer(withFinalizer)) -} - -func TestSetFinalizerIfEmpty(t *testing.T) { - noFinalizer := &v1.Job{} - withFinalizer := &v1.Job{} - withFinalizer.SetFinalizers([]string{"t1"}) - - assert.False(t, HasFinalizer(noFinalizer)) - SetFinalizerIfEmpty(noFinalizer, "f1") - assert.True(t, HasFinalizer(noFinalizer)) - assert.Equal(t, []string{"f1"}, noFinalizer.GetFinalizers()) - - SetFinalizerIfEmpty(withFinalizer, "f1") - assert.Equal(t, []string{"t1"}, withFinalizer.GetFinalizers()) -} - -func TestResetFinalizer(t *testing.T) { - noFinalizer := &v1.Job{} - ResetFinalizers(noFinalizer) - assert.Equal(t, []string{}, noFinalizer.GetFinalizers()) - - withFinalizer := &v1.Job{} - withFinalizer.SetFinalizers([]string{"t1"}) - ResetFinalizers(withFinalizer) - assert.Equal(t, []string{}, withFinalizer.GetFinalizers()) -} diff --git a/flytepropeller/pkg/controller/handler.go b/flytepropeller/pkg/controller/handler.go index 3e9f7526fc..42749adfe4 100644 --- a/flytepropeller/pkg/controller/handler.go +++ b/flytepropeller/pkg/controller/handler.go @@ -9,6 +9,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "go.opentelemetry.io/otel/trace" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" @@ -103,7 +104,7 @@ func (p *Propeller) TryMutateWorkflow(ctx context.Context, originalW *v1alpha1.F ctx = contextutils.WithResourceVersion(ctx, mutableW.GetResourceVersion()) maxRetries := uint32(p.cfg.MaxWorkflowRetries) // #nosec G115 - if IsDeleted(mutableW) || (mutableW.Status.FailedAttempts > maxRetries) { + if !mutableW.GetDeletionTimestamp().IsZero() || mutableW.Status.FailedAttempts > maxRetries { var err error func() { defer func() { @@ -125,7 +126,7 @@ func (p *Propeller) TryMutateWorkflow(ctx context.Context, originalW *v1alpha1.F if !mutableW.GetExecutionStatus().IsTerminated() { var err error - SetFinalizerIfEmpty(mutableW, FinalizerKey) + _ = controllerutil.AddFinalizer(mutableW, Finalizer) SetDefinitionVersionIfEmpty(mutableW, v1alpha1.LatestWorkflowDefinitionVersion) func() { @@ -210,7 +211,9 @@ func (p *Propeller) Handle(ctx context.Context, namespace, name string) error { } if w.GetExecutionStatus().IsTerminated() { - if HasCompletedLabel(w) && !HasFinalizer(w) { + // Checking for the old finalizer for backwards compatibility + // This should be eventually removed + if HasCompletedLabel(w) && !controllerutil.ContainsFinalizer(w, Finalizer) && !controllerutil.ContainsFinalizer(w, OldFinalizer) { logger.Debugf(ctx, "Workflow is terminated.") // This workflow had previously completed, let us ignore it return nil @@ -325,7 +328,9 @@ func (p *Propeller) streak(ctx context.Context, w *v1alpha1.FlyteWorkflow, wfClo // If the end result is a terminated workflow, we remove the labels // We add a completed label so that we can avoid polling for this workflow SetCompletedLabel(mutatedWf, time.Now()) - ResetFinalizers(mutatedWf) + _ = controllerutil.RemoveFinalizer(mutatedWf, Finalizer) + // Backwards compatibility. This should eventually be removed + _ = controllerutil.RemoveFinalizer(mutatedWf, OldFinalizer) } } @@ -387,7 +392,9 @@ func (p *Propeller) streak(ctx context.Context, w *v1alpha1.FlyteWorkflow, wfClo mutableW := w.DeepCopy() // catch potential indefinite update loop if mutatedWf.GetExecutionStatus().IsTerminated() { - ResetFinalizers(mutableW) + _ = controllerutil.RemoveFinalizer(mutableW, Finalizer) + // Backwards compatibility. This should eventually be removed + _ = controllerutil.RemoveFinalizer(mutableW, OldFinalizer) SetDefinitionVersionIfEmpty(mutableW, v1alpha1.LatestWorkflowDefinitionVersion) SetCompletedLabel(mutableW, time.Now()) msg := fmt.Sprintf("Workflow size has breached threshold. Finalized with status: %v", mutatedWf.GetExecutionStatus().GetPhase()) diff --git a/flytepropeller/pkg/controller/handler_test.go b/flytepropeller/pkg/controller/handler_test.go index 3469c1da80..a57a5fdead 100644 --- a/flytepropeller/pkg/controller/handler_test.go +++ b/flytepropeller/pkg/controller/handler_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin" "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core" @@ -249,7 +250,7 @@ func TestPropeller_Handle(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ ID: "w1", @@ -268,7 +269,7 @@ func TestPropeller_Handle(t *testing.T) { assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseSucceeding, r.GetExecutionStatus().GetPhase()) assert.False(t, HasCompletedLabel(r)) - assert.Equal(t, 1, len(r.Finalizers)) + assert.Equal(t, 2, len(r.Finalizers)) }) t.Run("handlingPanics", func(t *testing.T) { @@ -276,7 +277,7 @@ func TestPropeller_Handle(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ ID: "w1", @@ -294,7 +295,7 @@ func TestPropeller_Handle(t *testing.T) { assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseSucceeding, r.GetExecutionStatus().GetPhase()) assert.False(t, HasCompletedLabel(r)) - assert.Equal(t, 1, len(r.Finalizers)) + assert.Equal(t, 2, len(r.Finalizers)) assert.Equal(t, uint32(1), r.Status.FailedAttempts) }) @@ -303,7 +304,7 @@ func TestPropeller_Handle(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ ID: "w1", @@ -322,7 +323,7 @@ func TestPropeller_Handle(t *testing.T) { assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseSucceeding, r.GetExecutionStatus().GetPhase()) assert.False(t, HasCompletedLabel(r)) - assert.Equal(t, 1, len(r.Finalizers)) + assert.Equal(t, 2, len(r.Finalizers)) }) t.Run("retriesExhaustedFinalize", func(t *testing.T) { @@ -330,7 +331,7 @@ func TestPropeller_Handle(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ ID: "w1", @@ -351,7 +352,7 @@ func TestPropeller_Handle(t *testing.T) { r, err := s.Get(ctx, namespace, name) assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseFailed, r.GetExecutionStatus().GetPhase()) - assert.Equal(t, 0, len(r.Finalizers)) + assert.NotContains(t, r.Finalizers, Finalizer) assert.True(t, HasCompletedLabel(r)) assert.True(t, abortCalled) }) @@ -362,7 +363,7 @@ func TestPropeller_Handle(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, DeletionTimestamp: &n, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ @@ -381,7 +382,7 @@ func TestPropeller_Handle(t *testing.T) { r, err := s.Get(ctx, namespace, name) assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseAborted, r.GetExecutionStatus().GetPhase()) - assert.Equal(t, 0, len(r.Finalizers)) + assert.NotContains(t, r.Finalizers, Finalizer) assert.True(t, HasCompletedLabel(r)) }) @@ -420,7 +421,7 @@ func TestPropeller_Handle(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ ID: "w1", @@ -435,7 +436,7 @@ func TestPropeller_Handle(t *testing.T) { r, err := s.Get(ctx, namespace, name) assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseSuccess, r.GetExecutionStatus().GetPhase()) - assert.Equal(t, 0, len(r.Finalizers)) + assert.NotContains(t, r.Finalizers, Finalizer) assert.True(t, HasCompletedLabel(r)) }) @@ -444,7 +445,7 @@ func TestPropeller_Handle(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ ID: "w1", @@ -459,7 +460,7 @@ func TestPropeller_Handle(t *testing.T) { r, err := s.Get(ctx, namespace, name) assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseFailed, r.GetExecutionStatus().GetPhase()) - assert.Equal(t, 0, len(r.Finalizers)) + assert.NotContains(t, r.Finalizers, Finalizer) assert.True(t, HasCompletedLabel(r)) }) t.Run("failOnExecutionNotFoundError", func(t *testing.T) { @@ -638,7 +639,7 @@ func TestPropeller_Handle_TurboMode(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: name, Namespace: namespace, - Finalizers: []string{"f1"}, + Finalizers: []string{Finalizer, "f1"}, }, WorkflowSpec: &v1alpha1.WorkflowSpec{ ID: "w1", @@ -662,7 +663,7 @@ func TestPropeller_Handle_TurboMode(t *testing.T) { assert.NoError(t, err) assert.Equal(t, v1alpha1.WorkflowPhaseSucceeding, r.GetExecutionStatus().GetPhase()) assert.False(t, HasCompletedLabel(r)) - assert.Equal(t, 1, len(r.Finalizers)) + assert.Equal(t, 2, len(r.Finalizers)) }) t.Run("happy-nochange", func(t *testing.T) { @@ -843,7 +844,7 @@ func TestNewPropellerHandler_UpdateFailure(t *testing.T) { s.OnGetMatch(mock.Anything, mock.Anything, mock.Anything).Return(wf, nil) s.On("Update", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.Wrap(workflowstore.ErrWorkflowToLarge, "too large")).Once() s.On("Update", mock.Anything, mock.MatchedBy(func(w *v1alpha1.FlyteWorkflow) bool { - return w.Status.Phase == v1alpha1.WorkflowPhaseFailed && !HasFinalizer(w) && HasCompletedLabel(w) + return w.Status.Phase == v1alpha1.WorkflowPhaseFailed && !controllerutil.ContainsFinalizer(w, Finalizer) && HasCompletedLabel(w) }), mock.Anything).Return(nil, nil).Once() err := p.Handle(ctx, namespace, name) assert.NoError(t, err) diff --git a/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager.go b/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager.go index 431824dad2..6d558f818e 100644 --- a/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager.go +++ b/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager.go @@ -19,6 +19,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/util/workqueue" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/predicate" @@ -41,7 +42,12 @@ import ( "github.com/flyteorg/flyte/flytestdlib/promutils/labeled" ) -const finalizer = "flyte/flytek8s" +const ( + finalizer = "flyte.org/finalizer-k8s" + // Old non-domain-qualified finalizer for backwards compatibility + // This should eventually be removed + oldFinalizer = "flyte/flytek8s" +) const pluginStateVersion = 1 @@ -115,8 +121,7 @@ func (e *PluginManager) addObjectMetadata(taskCtx pluginsCore.TaskExecutionMetad } if cfg.InjectFinalizer && !e.plugin.GetProperties().DisableInjectFinalizer { - f := append(o.GetFinalizers(), finalizer) - o.SetFinalizers(f) + _ = controllerutil.AddFinalizer(o, finalizer) } if errs := validation.IsDNS1123Subdomain(o.GetName()); len(errs) > 0 { @@ -312,10 +317,10 @@ func (e *PluginManager) checkResourcePhase(ctx context.Context, tCtx pluginsCore return pluginsCore.DoTransition(p), nil } - if !p.Phase().IsTerminal() && o.GetDeletionTimestamp() != nil { + if !p.Phase().IsTerminal() && !o.GetDeletionTimestamp().IsZero() { // If the object has been deleted, that is, it has a deletion timestamp, but is not in a terminal state, we should // mark the task as a retryable failure. We've seen this happen when a kubelet disappears - all pods running on - // the node are marked with a deletionTimestamp, but our finalizers prevent the pod from being deleted. + // the node are marked with a deletionTimestamp, but our finalizer prevents the pod from being deleted. // This can also happen when a user deletes a Pod directly. failureReason := fmt.Sprintf("object [%s] terminated in the background, manually", nsName.String()) return pluginsCore.DoTransition(pluginsCore.PhaseInfoSystemRetryableFailure("UnexpectedObjectDeletion", failureReason, nil)), nil @@ -444,7 +449,7 @@ func (e PluginManager) Abort(ctx context.Context, tCtx pluginsCore.TaskExecution } if err != nil && !isK8sObjectNotExists(err) { - logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v/%v. Error: %v", + logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v/%v. Error: %v", resourceToFinalize.GetNamespace(), resourceToFinalize.GetName(), err) return err } @@ -452,17 +457,21 @@ func (e PluginManager) Abort(ctx context.Context, tCtx pluginsCore.TaskExecution return nil } -func (e *PluginManager) clearFinalizers(ctx context.Context, o client.Object) error { - if len(o.GetFinalizers()) > 0 { - o.SetFinalizers([]string{}) +// clearFinalizer removes the Flyte finalizer (if it exists) from the k8s resource +func (e *PluginManager) clearFinalizer(ctx context.Context, o client.Object) error { + // Checking for the old finalizer too for backwards compatibility. This should eventually be removed + // Go does short-circuiting and we have to make sure both are removed + finalizerRemoved := controllerutil.RemoveFinalizer(o, finalizer) + oldFinalizerRemoved := controllerutil.RemoveFinalizer(o, oldFinalizer) + if finalizerRemoved || oldFinalizerRemoved { err := e.kubeClient.GetClient().Update(ctx, o) if err != nil && !isK8sObjectNotExists(err) { - logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v/%v. Error: %v", + logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v/%v. Error: %v", o.GetNamespace(), o.GetName(), err) return err } } else { - logger.Debugf(ctx, "Finalizers are already empty for Resource with name: %v/%v", + logger.Debugf(ctx, "Finalizer is already cleared from Resource with name: %v/%v", o.GetNamespace(), o.GetName()) } return nil @@ -487,7 +496,7 @@ func (e *PluginManager) Finalize(ctx context.Context, tCtx pluginsCore.TaskExecu Steps: e.updateBackoffRetries, } - // Attempt to cleanup finalizers so that the object may be deleted/garbage collected. We try to clear them for all + // Attempt to cleanup finalizer so that the object may be deleted/garbage collected. We try to clear it for all // objects, regardless of whether or not InjectFinalizer is configured to handle all cases where InjectFinalizer is // enabled/disabled during object execution. var lastErr error @@ -507,14 +516,14 @@ func (e *PluginManager) Finalize(ctx context.Context, tCtx pluginsCore.TaskExecu // This must happen after sending admin event. It's safe against partial failures because if the event failed, we will // simply retry in the next round. If the event succeeded but this failed, we will try again the next round to send // the same event (idempotent) and then come here again... - if err := e.clearFinalizers(ctx, o); err != nil { + if err := e.clearFinalizer(ctx, o); err != nil { lastErr = err // retry is if there is a conflict in case the informer cache is out of sync if k8serrors.IsConflict(err) { - logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v. Error: %v. Retrying..", nsName, err) + logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v. Error: %v. Retrying..", nsName, err) return false, nil } - logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v. Error: %v", nsName, err) + logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v. Error: %v", nsName, err) return true, err } return true, nil diff --git a/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager_test.go b/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager_test.go index 1d8d5064d9..a02c32dca1 100644 --- a/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager_test.go +++ b/flytepropeller/pkg/controller/nodes/task/k8s/plugin_manager_test.go @@ -987,6 +987,27 @@ func TestPluginManager_AddObjectMetadata(t *testing.T) { assert.Equal(t, 0, len(o.GetFinalizers())) }) + t.Run("Inject finalizers", func(t *testing.T) { + p := pluginsk8sMock.Plugin{} + p.OnGetProperties().Return(k8s.PluginProperties{DisableInjectFinalizer: false}) + pluginManager := PluginManager{plugin: &p} + // enable finalizer injection + cfg.InjectFinalizer = true + o := &v1.Pod{} + pluginManager.addObjectMetadata(tm, o, cfg) + assert.Equal(t, genName, o.GetName()) + // empty OwnerReference since we are ignoring + assert.Equal(t, 1, len(o.GetOwnerReferences())) + assert.Equal(t, ns, o.GetNamespace()) + assert.Equal(t, map[string]string{ + "cluster-autoscaler.kubernetes.io/safe-to-evict": "false", + "aKey": "aVal", + }, o.GetAnnotations()) + assert.Equal(t, l, o.GetLabels()) + assert.Equal(t, 1, len(o.GetFinalizers())) + assert.Contains(t, o.GetFinalizers(), finalizer) + }) + } func TestResourceManagerConstruction(t *testing.T) { @@ -1015,15 +1036,16 @@ func TestFinalize(t *testing.T) { tctx := getMockTaskContext(PluginPhaseStarted, PluginPhaseStarted) o := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: tctx.TaskExecutionMetadata().GetTaskExecutionID().GetGeneratedName(), - Namespace: tctx.TaskExecutionMetadata().GetNamespace(), + Name: tctx.TaskExecutionMetadata().GetTaskExecutionID().GetGeneratedName(), + Namespace: tctx.TaskExecutionMetadata().GetNamespace(), + Finalizers: []string{finalizer}, }, } assert.NoError(t, fakeKubeClient.GetClient().Create(ctx, o)) p.OnBuildIdentityResource(ctx, tctx.TaskExecutionMetadata()).Return(o, nil) - pluginManager := PluginManager{plugin: &p, kubeClient: fakeKubeClient} + pluginManager := PluginManager{plugin: &p, kubeClient: fakeKubeClient, updateBackoffRetries: 5} actualO := &v1.Pod{} // Assert the object exists before calling finalize assert.NoError(t, fakeKubeClient.GetClient().Get(ctx, k8stypes.NamespacedName{ @@ -1061,7 +1083,7 @@ func TestFinalize(t *testing.T) { assert.NoError(t, fakeKubeClient.GetClient().Create(ctx, o)) p.OnBuildIdentityResource(ctx, tctx.TaskExecutionMetadata()).Return(o, nil) - pluginManager := PluginManager{plugin: &p, kubeClient: fakeKubeClient} + pluginManager := PluginManager{plugin: &p, kubeClient: fakeKubeClient, updateBackoffRetries: 5} actualO := &v1.Pod{} // Assert the object exists before calling finalize assert.NoError(t, fakeKubeClient.GetClient().Get(ctx, k8stypes.NamespacedName{ diff --git a/go.mod b/go.mod index 37e8aa4301..5f72dce3c4 100644 --- a/go.mod +++ b/go.mod @@ -144,7 +144,6 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/ncw/swift v1.0.53 // indirect - github.com/nxadm/tail v1.4.11 // indirect github.com/ory/fosite v0.42.2 // indirect github.com/ory/go-acc v0.2.6 // indirect github.com/ory/go-convenience v0.1.0 // indirect From 9193dd65081f0d25b693049c8095fa9ab53fb0df Mon Sep 17 00:00:00 2001 From: David Espejo <82604841+davidmirror-ops@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:15:44 -0500 Subject: [PATCH 13/15] Update contribution guides (#6150) * Update guidelines and add links Signed-off-by: davidmirror-ops * Update PR template Signed-off-by: davidmirror-ops * Move instructions between pages for clarity Signed-off-by: davidmirror-ops * Update links and hours for community syncs Signed-off-by: davidmirror-ops * Add notes about PR labels Signed-off-by: davidmirror-ops * Replace permissions warning Signed-off-by: davidmirror-ops * Fix CI test results Signed-off-by: davidmirror-ops --------- Signed-off-by: davidmirror-ops --- .github/PULL_REQUEST_TEMPLATE.md | 11 ++++++ .../manifests/complete-agent.yaml | 4 +- .../sandbox-bundled/manifests/complete.yaml | 4 +- docker/sandbox-bundled/manifests/dev.yaml | 4 +- docs/community/contribute/contribute_code.rst | 36 ++--------------- docs/community/contribute/contribute_docs.md | 35 ++++++++++++++++- docs/community/contribute/index.rst | 39 +++++++++++++------ docs/community/index.rst | 23 +++++++---- 8 files changed, 98 insertions(+), 58 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3956f99afb..e58f159c12 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -33,6 +33,17 @@ If tests were added, say they were added here. Please make sure to add some test If it was tested in a way different from regular unit tests, please clarify how you tested step by step, ideally copy and paste-able, so that other reviewers can test and check, and descendants can verify in the future. If tests were not added, please describe why they were not added and/or why it was difficult to add. --> +### Labels + +Please add one or more of the following labels to categorize your PR: +- **added**: For new features. +- **changed**: For changes in existing functionality. +- **deprecated**: For soon-to-be-removed features. +- **removed**: For features being removed. +- **fixed**: For any bug fixed. +- **security**: In case of vulnerabilities + +This is important to improve the readability of release notes. ### Setup process diff --git a/docker/sandbox-bundled/manifests/complete-agent.yaml b/docker/sandbox-bundled/manifests/complete-agent.yaml index 3a5a33b1d6..e85294e86b 100644 --- a/docker/sandbox-bundled/manifests/complete-agent.yaml +++ b/docker/sandbox-bundled/manifests/complete-agent.yaml @@ -823,7 +823,7 @@ type: Opaque --- apiVersion: v1 data: - haSharedSecret: ZVg2MDdXYnJyNXlYUWlLSA== + haSharedSecret: VFRKYXBKM2xsTERQb1ZDaQ== proxyPassword: "" proxyUsername: "" kind: Secret @@ -1420,7 +1420,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: 4d048d7850540d6862f070a28041c7c814d011e537872aecce2159789db2db79 + checksum/secret: 4c7bc4fbd20227034bda9ead9cd941c94879028d6920b98113f9a08ef3c6f9d9 labels: app: docker-registry release: flyte-sandbox diff --git a/docker/sandbox-bundled/manifests/complete.yaml b/docker/sandbox-bundled/manifests/complete.yaml index 82cb2d9641..93daed5dff 100644 --- a/docker/sandbox-bundled/manifests/complete.yaml +++ b/docker/sandbox-bundled/manifests/complete.yaml @@ -805,7 +805,7 @@ type: Opaque --- apiVersion: v1 data: - haSharedSecret: VXRnT3hJaE9CMEZldDJubg== + haSharedSecret: Zm4xWHVaRlNsb2EyVFFIVg== proxyPassword: "" proxyUsername: "" kind: Secret @@ -1369,7 +1369,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: 8a6224d331e9ccebb789367315d7f9677d9f4c7886640c8baeea547432cca5ad + checksum/secret: fdbda8db15a09ca5943cc534a824402836c98722de81d1631c45099a8e04b043 labels: app: docker-registry release: flyte-sandbox diff --git a/docker/sandbox-bundled/manifests/dev.yaml b/docker/sandbox-bundled/manifests/dev.yaml index 7f7524f5ba..08efa97dde 100644 --- a/docker/sandbox-bundled/manifests/dev.yaml +++ b/docker/sandbox-bundled/manifests/dev.yaml @@ -499,7 +499,7 @@ metadata: --- apiVersion: v1 data: - haSharedSecret: bnFsU3VrQTFsRmd0azdvcQ== + haSharedSecret: RjY3OEtOeFVDMjFabkI0SA== proxyPassword: "" proxyUsername: "" kind: Secret @@ -934,7 +934,7 @@ spec: metadata: annotations: checksum/config: 8f50e768255a87f078ba8b9879a0c174c3e045ffb46ac8723d2eedbe293c8d81 - checksum/secret: 492f9045abb64dc1e4f8fa90bb957960ea3ccd8d03b424a3a2fa2a83bfb87531 + checksum/secret: 6ab17d37fe9743709a5aa2a140c06a7a25fe33cfe4d6c0cbcb2ddf0a2dcf1675 labels: app: docker-registry release: flyte-sandbox diff --git a/docs/community/contribute/contribute_code.rst b/docs/community/contribute/contribute_code.rst index 21b05e20a2..2eed2f12e2 100644 --- a/docs/community/contribute/contribute_code.rst +++ b/docs/community/contribute/contribute_code.rst @@ -9,6 +9,9 @@ Contributing code To understand how the below components interact with each other, refer to :ref:`Understand the lifecycle of a workflow `. +.. note:: + With the exception of ``flytekit``, the below components are maintained in the `flyte `__ monorepo. + .. figure:: https://raw.githubusercontent.com/flyteorg/static-resources/main/flyte/contribution_guide/dependency_graph.png :alt: Dependency graph between various flyteorg repos :align: center @@ -25,39 +28,6 @@ To understand how the below components interact with each other, refer to :ref:` * - **Purpose**: Deployment, Documentation, and Issues * - **Languages**: RST -In the ``flyteorg/flyte`` root directory you can run ``make dev-docs`` to build the documentation locally. The generated documentation will be in the ``docs/_build/html`` directory. - -**Setup process** - -1. First you need to make sure you can run linux/amd64 container -2. Run the following commands to build the documentation and serve it locally - -.. prompt:: bash $ - - make dev-docs - python -m http.server --directory docs/_build/html - -3. Go to http://localhost:8000 to see the documentation. - -**Supported environment variables of** ``make dev-docs`` - -* ``DEV_DOCS_WATCH``: If set, the docs will be built and served using `sphinx-autobuild `__ for live updates. -* ``FLYTEKIT_LOCAL_PATH``: If set, the local path to flytekit will be used instead of the source code from the ``flyteorg/flytekit repo``. -* ``FLYTECTL_LOCAL_PATH``: If set, the local path to flytectl will be used instead of the source code from the ``flyteorg/flytectl repo``. -* ``FLYTESNACKS_LOCAL_PATH``: If set, the local path to flytesnacks will be used instead of the source code from the ``flyteorg/flytesnacks`` repo. - -For example, to use the local flytekit source code instead of the source code from the ``flyteorg/flytekit`` repo, run ``export FLYTEKIT_LOCAL_PATH=/path/to/flytekit`` before running ``make dev-docs``. - -**Alternative conda setup steps** - -* Install ``conda``. - * We recommend Miniconda installed with an `official installer `__. -* Install `conda-lock `__. -* In the ``flyteorg/flyte`` root directory run: - * ``conda-lock install --name monodocs-env monodocs-environment.lock.yaml`` - * ``conda activate monodocs-env`` - * ``pip install ./flyteidl`` - ``flyteidl`` ************ diff --git a/docs/community/contribute/contribute_docs.md b/docs/community/contribute/contribute_docs.md index 7c1d47ffc8..4fd6d78452 100644 --- a/docs/community/contribute/contribute_docs.md +++ b/docs/community/contribute/contribute_docs.md @@ -17,7 +17,40 @@ The Flyte documentation comprises the following types: * **{ref}`Deployment documentation `:** Guidance on deploying and configuring the Flyte backend. * **{doc}`API documentation <../../api/index>`:** flytekit, flytectl, and flyteidl documentation. -For minor edits that don't require a local setup, you can edit the page in GitHub page to propose improvements. +For minor edits that don't require a local setup, you can edit the page in GitHub page to propose improvements.} + +In the ``flyteorg/flyte`` root directory you can run ``make dev-docs`` to build the documentation locally. The generated documentation will be in the ``docs/_build/html`` directory. + +**Setup process** + +1. First you need to make sure you can run linux/amd64 container +2. From the root of your fork, run the following commands to build the documentation and serve it locally + +.. prompt:: bash $ + + make dev-docs + python -m http.server --directory docs/_build/html + +3. Go to http://localhost:8000 to see the documentation. + +**Supported environment variables of** ``make dev-docs`` + +* ``DEV_DOCS_WATCH``: If set, the docs will be built and served using `sphinx-autobuild `__ for live updates. +* ``FLYTEKIT_LOCAL_PATH``: If set, the local path to flytekit will be used instead of the source code from the ``flyteorg/flytekit repo``. +* ``FLYTECTL_LOCAL_PATH``: If set, the local path to flytectl will be used instead of the source code from the ``flyteorg/flytectl repo``. +* ``FLYTESNACKS_LOCAL_PATH``: If set, the local path to flytesnacks will be used instead of the source code from the ``flyteorg/flytesnacks`` repo. + +For example, to use the local flytekit source code instead of the source code from the ``flyteorg/flytekit`` repo, run ``export FLYTEKIT_LOCAL_PATH=/path/to/flytekit`` before running ``make dev-docs``. + +**Alternative conda setup steps** + +* Install ``conda``. + * We recommend Miniconda installed with an `official installer `__. +* Install `conda-lock `__. +* In the ``flyteorg/flyte`` root directory run: + * ``conda-lock install --name monodocs-env monodocs-environment.lock.yaml`` + * ``conda activate monodocs-env`` + * ``pip install ./flyteidl`` ## Contributing to user guide and deployment documentation diff --git a/docs/community/contribute/index.rst b/docs/community/contribute/index.rst index eb13f5d73f..c3c243db24 100644 --- a/docs/community/contribute/index.rst +++ b/docs/community/contribute/index.rst @@ -7,7 +7,6 @@ Contributing to Flyte .. tags:: Contribute, Basic Thank you for taking the time to contribute to Flyte! -Please read our `Code of Conduct `__ before contributing to Flyte. Here are some guidelines for you to follow, which will make your first and follow-up contributions easier. @@ -18,24 +17,42 @@ TL;DR: Find the repo-specific contribution guidelines in the :ref:`Component Ref An issue tagged with `good first issue `__ is the best place to start for first-time contributors. -**Appetizer for every repo: Fork and clone the concerned repository. Create a new branch on your fork and make the required changes. Create a pull request once your work is ready for review.** +**Fork and clone the concerned repository. Create a new branch on your fork and make the required changes. Create a pull request once your work is ready for review.** .. note:: To open a pull request, refer to `GitHub's guide `__ for detailed instructions. Example PR for your reference: `GitHub PR `__. -A couple of checks are introduced to help maintain the robustness of the project. +Several checks are introduced to help maintain the robustness of the project: #. To get through DCO, sign off on every commit (`Reference `__) -#. To improve code coverage, write unit tests to test your code -#. Make sure all the tests pass. If you face any issues, please let us know +#. To improve code coverage, write unit tests to test your code. +#. Make sure all the tests pass. If you face any issues, please let us know in the `#contribute `__ channel +#. Format your Go code with ``golangci-lint`` followed by ``goimports`` (use ``make lint`` and ``make goimports``) +#. Format your Python code with ``black`` and ``isort`` (use ``make fmt``). +#. If make targets are not available, you can manually format the code. -On a side note, format your Go code with ``golangci-lint`` followed by ``goimports`` (use ``make lint`` and ``make goimports``), and Python code with ``black`` and ``isort`` (use ``make fmt``). -If make targets are not available, you can manually format the code. -Refer to `Effective Go `__, `Black `__, and `Isort `__ for full coding standards. +.. note:: + Refer to `Effective Go `__, `Black `__, and `Isort `__ for full coding standards. + +As you become more involved with the project, you may be able to be added as a committer to the repos you're working on. Checkout the `Flyte Contributor Ladder `__ to learn more. + +Before submitting your PR +************************** + +We strongly encourage you to add one of these labels to your Pull Request: -As you become more involved with the project, you may be able to be added as a contributor to the repos you're working on, -but there is a medium term effort to move all development to forks. +- **added**: For new features. +- **changed**: For changes in existing functionality. +- **deprecated**: For soon-to-be-removed features. +- **removed**: For features being removed. +- **fixed**: For any bug fixes. +- **security**: In case of vulnerabilities + +This is helpful to build human-readable release notes. `Learn more `__ + +.. note:: + Learn how to apply a label to a PR in the `Github docs `__. 🐞 File an issue ================ @@ -53,7 +70,7 @@ We use `GitHub Issues `__ for issue tr If none of the above fit your requirements, file a `blank `__ issue. Also, add relevant labels to your issue. For example, if you are filing a Flytekit plugin request, add the ``flytekit`` label. -For feedback at any point in the contribution process, feel free to reach out to us on `Slack `__. +For feedback at any point in the contribution process, feel free to reach out to us on `Slack `__. .. toctree:: :maxdepth: 1 diff --git a/docs/community/index.rst b/docs/community/index.rst index 2e1e740c98..889f0eda97 100644 --- a/docs/community/index.rst +++ b/docs/community/index.rst @@ -27,16 +27,25 @@ Please join us on: :alt: LinkedIn -Open Source Community Meeting ------------------------------ +Community Sync +-------------- + +#. When: First tuesday of every month, 9:00 AM Pacific Time. +#. Where: live streamed on `YouTube `__ and `LinkedIn `__. +#. Watch the `recordings `__ +#. Import the public `calendar `_ to not miss any event. +#. If you want to give a presentation to the Flyte community, please fill out `this form __`. We're eager to learn from you! -When: Every other Thursday, 11:00 AM Pacific Time. You're welcome to join and learn from other community members sharing their experiences with Flyte or any other technology from the AI ecosystem. -Check out the event details and add it to your `calendar `_, or just pop in! -.. image:: https://img.shields.io/badge/Join-Zoom-blue?style=for-the-badge - :target: https://www.addevent.com/event/EA7823958 - :alt: Zoom Link +Contributor's Sync +------------------ + +#. When: every 2 weeks on Thursdays. Alternating schedule between 11:00 am PT and 7:00 am PT. +#. Where: live on `Zoom `__. +#. Purpose: address questions from new contributors, discuss active initiatives and RFCs. +#. Import the public `calendar `_ to not miss any event. + Newsletter ---------- From 4db5a60840bb99642a7e25625e3984658eb6795f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=9F=E5=AE=B6=E7=91=8B?= <36886416+JiangJiaWei1103@users.noreply.github.com> Date: Fri, 10 Jan 2025 03:54:59 +0800 Subject: [PATCH 14/15] docs: Fix fd doc code lines (#6149) Signed-off-by: JiaWei Jiang --- docs/user_guide/data_types_and_io/flytedirectory.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user_guide/data_types_and_io/flytedirectory.md b/docs/user_guide/data_types_and_io/flytedirectory.md index 82cc5ab2a0..d5ab267992 100644 --- a/docs/user_guide/data_types_and_io/flytedirectory.md +++ b/docs/user_guide/data_types_and_io/flytedirectory.md @@ -18,7 +18,7 @@ To begin, import the libraries: ```{literalinclude} /examples/data_types_and_io/data_types_and_io/folder.py :caption: data_types_and_io/folder.py -:lines: 1-10 +:lines: 1-9 ``` Building upon the previous example demonstrated in the {std:ref}`file ` section, @@ -100,7 +100,7 @@ Here is a simple example, you can accept a `FlyteDirectory` as an input, walk th ```{literalinclude} /examples/data_types_and_io/data_types_and_io/file_streaming.py :caption: data_types_and_io/file_streaming.py -:lines: 23-33 +:lines: 24-34 ``` [flytesnacks]: https://github.com/flyteorg/flytesnacks/tree/master/examples/data_types_and_io/ From b0107470246d3f2c0ff553305df2c79b3e650902 Mon Sep 17 00:00:00 2001 From: V <0426vincent@gmail.com> Date: Thu, 9 Jan 2025 12:07:17 -0800 Subject: [PATCH 15/15] docs: update URL in local workflow execution guide to reflect project name (#6137) Signed-off-by: Vincent <0426vincent@gmail.com> --- .../running_a_workflow_locally.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_guide/getting_started_with_workflow_development/running_a_workflow_locally.md b/docs/user_guide/getting_started_with_workflow_development/running_a_workflow_locally.md index ce549889f0..921657b114 100644 --- a/docs/user_guide/getting_started_with_workflow_development/running_a_workflow_locally.md +++ b/docs/user_guide/getting_started_with_workflow_development/running_a_workflow_locally.md @@ -144,7 +144,7 @@ pyflyte run --remote -p my-project -d development example.py wf --name Ada You should see a URL to the workflow execution on your demo Flyte cluster, where `` is a unique identifier for the workflow execution: ```{prompt} bash $ -Go to http://localhost:30080/console/projects/flytesnacks/domains/development/executions/ to see execution in the console. +Go to http://localhost:30080/console/projects/my-project/domains/development/executions/ to see execution in the console. ``` ### Inspecting a workflow run in the FlyteConsole web interface