{"id":13709646,"url":"https://github.com/dbhi/run","last_synced_at":"2026-01-14T12:53:09.135Z","repository":{"id":34404022,"uuid":"177232530","full_name":"dbhi/run","owner":"dbhi","description":"Yet another task execution/automation package for complex dependency graphs","archived":false,"fork":false,"pushed_at":"2023-02-13T12:57:34.000Z","size":217,"stargazers_count":8,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-11T10:43:58.154Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dbhi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-23T02:00:59.000Z","updated_at":"2023-07-20T13:34:29.000Z","dependencies_parsed_at":"2024-06-19T13:34:06.106Z","dependency_job_id":"0b285ecd-2f90-4ef9-8b59-892e7bef3743","html_url":"https://github.com/dbhi/run","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dbhi/run","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbhi%2Frun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbhi%2Frun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbhi%2Frun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbhi%2Frun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dbhi","download_url":"https://codeload.github.com/dbhi/run/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbhi%2Frun/sbom","scorecard":{"id":328903,"data":{"date":"2025-08-11","repo":{"name":"github.com/dbhi/run","commit":"79d4ce4b8ab7decea7c27d6750055aef2bfa291d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/Pipeline.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:81: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:83: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:107: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:110: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:115: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Pipeline.yml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/dbhi/run/Pipeline.yml/main?enable=pin","Warn: goCommand not pinned by hash: .github/workflows/Pipeline.yml:41","Info:   0 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   2 out of   3 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T03:07:36.492Z","repository_id":34404022,"created_at":"2025-08-18T03:07:36.492Z","updated_at":"2025-08-18T03:07:36.492Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420814,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T23:00:43.060Z","updated_at":"2026-01-14T12:53:09.115Z","avatar_url":"https://github.com/dbhi.png","language":"Go","funding_links":[],"categories":["Programming"],"sub_categories":["Tasks runners"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./logo.png\" width=\"550\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca title=\"GoDoc\" href=\"https://godoc.org/github.com/dbhi/run/lib\"\u003e\u003cimg src=\"https://img.shields.io/badge/godoc-reference-5272B4.svg?longCache=true\u0026style=flat-square\u0026logo=go\u0026logoColor=fff\"\u003e\u003c/a\u003e\u003c!--\n  --\u003e\n  \u003ca title=\"Releases\" href=\"https://github.com/dbhi/run/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/commits-since/dbhi/run/latest.svg?longCache=true\u0026style=flat-square\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n`run` is a task execution automation package that analyses complex dependency graphs ([multitree](https://en.wikipedia.org/wiki/Multitree) [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph)), generates filtered subgraphs for each target and provides ordered lists of tasks through [topological sorting](https://en.wikipedia.org/wiki/Topological_sorting). `run` is neither a replacement nor a wrapper for [Make](https://en.wikipedia.org/wiki/Make_(software)), instead it is a complement. The main use case is the combination of multiple build steps, each with a different tool which has it's own build system (be it `make`, `cmake`, `go build`, etc.), and probably involving parameters provided through JSON files, CLI arguments and/or environment variables.\n\n`run/lib` is meant to be used imported to other [golang](https://golang.org/) projects, such as CLI tools or web services. This allows golang developers to make the best of third-party libraries to process data and handle parallel (concurrent) execution seamlessly.\n\n`run/cli` is an example implementation of such a CLI tool which is based on [spf13/cobra](https://github.com/spf13/cobra) and [spf13/viper](https://github.com/spf13/viper/) along with `run/lib`. This is provided as a reference of how to interact with the API of `run/lib`, but it can be used as a standalone tool.\n\n`run` is built on top of [gonum](https://www.gonum.org/). Precisely, types, interfaces and functions defined in [gonum/graph](https://github.com/gonum/gonum/tree/master/graph) ([godoc.org/gonum.org/v1/gonum/graph](https://godoc.org/gonum.org/v1/gonum/graph)) are used to manipulate graphs. Therefore, `run` relies on the list of input formats supported by the package. In the examples, [Graphviz](https://www.graphviz.org/)'s [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) language is used, which is a widespread output format supported by many tools. For example, [lindenb/makefile2graph](https://github.com/lindenb/makefile2graph) allows to analyse makefiles, and [kisielk/godepgraph](https://github.com/kisielk/godepgraph) generates *a dependency graph of Go packages*.\n\n# Usage\n\nThe main input is a large complex graph where developers put the dependencies of their multiple workflows. Some of them are cross-related, some are independent dependency chains. This can be provided as a `graphviz` `dot` file (e.g. [`example/graph.dot`](./example/graph.dot)).\n\nThat's enough for basic features, such as reducing the complexity, filtering the nodes/edges, getting topologically ordered lists, etc. In order use execution features, the context of each task/job needs to be defined. This is currently done through either a JSON file (e.g. [`example/config.json`](./example/graph.dot)) or golang sources.\n\n\u003e NOTE: tasks/jobs cannot be defined through golang sources at runtime, unless golang is available. If pre-built binaries are used, new tasks/jobs can only be defined through JSON files.\n\n\u003e NOTE: in the discussion about similar projects below some info is provided about other input formats that we would like to support in the future.\n\n## Induce\n\n``` bash\nrun induce -g graph.json -o subgraphs leafs\n# OR\nrun induce -c config.json -o subgraphs leafs\n# note that '\"graph\": \"graph.dot\"' is defined in 'config.json'\n```\n\nGenerates a DOT subgraph in subdir `subgraphs` for each of the leafs in in `graph.dot`. Each subgraph includes only the dependencies required to build the corresponding leaf.\n\n\u003e WIP:\n\u003e - [x] allow to induce the graph of a single leaf.\n\u003e - [x] allow to induce the graph of the nodes that depend on a root.\n\u003e - [x] allow to induce the graph of a single root.\n\u003e - allow to induce the graph of a mid node (either forward, reverse or both).\n\n\u003e HINT: the subgraphs can be shown in a web frontend, so the user can select to visualize all the dependecies or to choose a single target and show the corresponding subgraph.\n\n## List\n\n``` bash\nrun list -g graph.json NODE\n# OR\nrun list -c config.json NODE\n```\n\nReturns an ordered list of tasks/jobs required to execute the given target NODE. The target can be any leaf or mid vertex.\n\n\u003e WIP:\n\u003e ``` bash\n\u003e run list -c config.json NODE[:FILTER]\n\u003e ```\n\u003e\n\u003e Returns an ordered list of tasks/jobs required to execute the given target NODE. The \u003e target can be any leaf or mid vertex. The optional argument `FILTER` allows to \u003e filter the list to include only a subset of the tasks in the subgraphs corresponding \u003e to the node. It can be either of:\n\u003e - `\u003eFNODE` jobs that allow build FNODE.\n\u003e - `FNODE\u003e` jobs that depend on FNODE.\n\u003e - `\u003eFNODE\u003e` jobs that allow to build FNODE and those that depend on it.\n\u003e\n\u003e For example:\n\u003e\n\u003e ``` bash\n\u003e # run list -c config.json bin\n\u003e\n\u003e # run list -c config.json bin:\u003eobjB\n\u003e # run list -c config.json bin:objA\u003e\n\u003e # run list -c config.json bin:\u003ebuildB\u003e\n\u003e ```\n\n## Exec\n\n``` bash\nrun exec -g graph.json NODE\n# note that the context and logic of the jobs must have been previously defined and built into 'run'\n# OR\nrun exec -c config.json NODE\n```\n\nExecutes all the tasks until NODE (included), in topological order.\n\n\u003e WIP:\n\u003e ``` bash\n\u003e run exec -c config.json NODE[:EXCLUDE]\n\u003e ```\n\u003e\n\n# References\n\n- [gonum](https://www.gonum.org)\n  - [godoc.org/gonum.org/v1/gonum](https://godoc.org/gonum.org/v1/gonum)\n  - [gonum/gonum#910](https://github.com/gonum/gonum/issues/910)\n    - [Preserving labels when marshaling a dot graph](https://groups.google.com/forum/#!topic/gonum-dev/xupu8gEmuIs)\n    - [godoc.org/github.com/kortschak/graphprac](https://godoc.org/github.com/kortschak/graphprac)\n- [semver.org](https://semver.org)\n- [keepachangelog.com](https://keepachangelog.com)\n- [dnaeon.github.io/graphs-and-clojure](http://dnaeon.github.io/graphs-and-clojure/)\n\n# Similar projects\n\nUse cases for `run` are similar to those for other tools such as:\n\n- [taskfile.dev](https://taskfile.dev) ([go-task/task](https://github.com/go-task/task)): a task runner/simpler Make alternative written in Go.\n  - Users need to write all the configuration details in one or multiple `Taskfile.yml` files. We want to support this. We might accept `Taskfile.yml` files indeed. But this should not be the single source of configuration.\n  - Dependencies are described explicitly. A different syntax is used to define dependencies that can be executed concurrently ('dep') and those that need to be executed serially ('task'). A dependency tree is derived, which is a specific type of dependency graph. As a result, some dependencies/tasks are built multiple times, if required by multiple jobs. Instead, we want to process the dependencies as a graph, and be able to reduce and topologically sort the list of tasks.\n  - Some golang features are used to handle OS specific tasks. This is something we might want to support.\n  - Sources and artifacts are explicitly listed through `sources` and `generates`, respectively. This allows to watch for changes and also to clean the artifacts. We want to support both features. However, we should not constrain the format to specific file paths. Instead we should support either expansion of wildcard or regexps.\n  - Golang templating features can be used in the `Taskfile.yml` file. We might want to support this.\n  - Wen multiple tasks are executed concurrently, the output can be set to `interleaved`, `group` or `prefixed`. We want to support this feature, although we will probably use a different approach.\n  - The tool is distributed as a single static binary. We want to do this too.\n- [magefile.org/](https://magefile.org/) ([magefile/mage](https://github.com/magefile/mage)): a Make/rake-like build tool using Go.\n  - Users need to write all the configuration details in one or multiple golang sources. This offers great flexibility and is a very powerful approach. We definitely want to support this approach, but this should not be the single source of configuration.\n  - Golang is required on the target platform. If pre-built, it is not possible to later define additional tasks ('targets') without golang. We do not want golang to be a required on the target platform in order to add jobs to the configuration which where not defined when the tool was built.\n  - Target aliases and Namespaces are supported. This is something we want to do too.\n  - `context` is supported. This is something we might want to support.\n  - Dependencies are described explicitly and different functions are used (`Deps` or `SerialDeps`). A dependency graph is built so that each dependency is guaranteed to be run exactly one. This is something we want to support too, but it should not be the single input source to the graph. We want to also support filtering some of the tasks at runtime.\n  - Two functions are provided to watch files. `target.Path` watches a directory or file not recursively and `target.Dir` watches a directory recursively.\n  - It is available as a compile-in library and three helper libraries are provided (`mg`, `sh` and `target`). At some point, we might find it interesting to directly integrate `run` and `mage`. Further analysis is required to do so.\n    - `run` can import some features from the `mage` API, transparently to the user.\n    - `run` can behave as a frontend/extension to `mage` which:\n      - Allows to read add 'target' configurations from other sources at runtime (i.e. DOT graphs or `Taskfile.yml` files).\n      - Provide generic functions to execute the targets defined through other sources.\n- [dogtools/dog](https://github.com/dogtools/dog)\n\nTherefore, it can be said that one of the purposes of `run` is to somehow integrate them.\n\n# ToDo for v1.0.0\n\n- We want to be able to retrieve the topological order of a subset of nodes in one of the subgraphs. We are evaluating three approaches:\n  - Retrieve the topological order of the subgraph and then remove the items that are to be ignored.\n  - Generate a subsubgraph from the subgraph and retrieve the topological order.\n  - We feel that we will need both: first generate a subsubgraph and then optionally remove some items from the topological order.\n- Propose `gonum/graph/dep`.\n- Support minimal web GUI to show subgraphs, subsubgraphs and task lists.\n- Provide basic example implementation of 'Exec'.\n- Allow to decide whether a target needs to be regenerated by comparing file modification times.\n- Merge graphs from different sources which might share some nodes and edges.\n- Dry run mode\n- Go's template engine\n- ignore certain tasks in a list\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbhi%2Frun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdbhi%2Frun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbhi%2Frun/lists"}