diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 830e671301..d2c7d29971 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,13 +3,18 @@ name: Bug Report about: Use this to report bugs and issues --- -> Thanks for your bug report! -> -> Before submitting this issue, please make sure the same problem was -> not already reported by someone else. -> -> Please describe the bug you're facing. Consider pasting example -> Taskfiles showing how to reproduce the problem. + - Task version: -- Operating System: +- Operating system: +- Experiments enabled: diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 41d78a398b..6a711ee1f4 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -3,9 +3,13 @@ name: Feature Request about: Use this to make feature requests --- -> Describe in detail what feature do you want to see in Task. -> Give examples if possible. -> -> Please, search if this wasn't proposed before, and if this is more like an idea -> than a strong feature request, consider opening a -> [discussion](https://github.com/go-task/task/discussions) instead. + diff --git a/.github/workflows/issue-experiment.yml b/.github/workflows/issue-experiment.yml new file mode 100644 index 0000000000..02577b9233 --- /dev/null +++ b/.github/workflows/issue-experiment.yml @@ -0,0 +1,123 @@ +name: issue experiment + +on: + issues: + types: [labeled] + +jobs: + issue-experiment-proposed: + if: github.event.label.name == format('experiment{0} proposed', ':') + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + github-token: ${{secrets.GH_PAT}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This issue has been marked as an experiment proposal! :test_tube: It will now enter a period of consultation during which we encourage the community to provide feedback on the proposed design. Please see the [experiment workflow documentation](https://taskfile.dev/experiments/workflow) for more information on how we release experiments.' + }) + issue-experiment-draft: + if: github.event.label.name == format('experiment{0} draft', ':') + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + github-token: ${{secrets.GH_PAT}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This experiment has been marked as a draft! :sparkles: This means that an initial implementation has been added to the latest release of Task! You can find information about this experiment and how to enable it in our [experiments documentation](https://taskfile.dev/experiments). Please see the [experiment workflow documentation](https://taskfile.dev/experiments/workflow) for more information on how we release experiments.' + }) + issue-experiment-candidate: + if: github.event.label.name == format('experiment{0} candidate', ':') + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + github-token: ${{secrets.GH_PAT}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This experiment has been marked as a candidate! :fire: This means that the implementation is nearing completion and we are entering a period for final comments and feedback! You can find information about this experiment and how to enable it in our [experiments documentation](https://taskfile.dev/experiments). Please see the [experiment workflow documentation](https://taskfile.dev/experiments/workflow) for more information on how we release experiments.' + }) + issue-experiment-stable: + if: github.event.label.name == format('experiment{0} stable', ':') + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + github-token: ${{secrets.GH_PAT}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This experiment has been marked as stable! :metal: This means that the implementation is now final and ready to be released. No more changes will be made and the experiment is safe to use in production! You can find information about this experiment and how to enable it in our [experiments documentation](https://taskfile.dev/experiments). Please see the [experiment workflow documentation](https://taskfile.dev/experiments/workflow) for more information on how we release experiments.' + }) + issue-experiment-released: + if: github.event.label.name == format('experiment{0} released', ':') + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + github-token: ${{secrets.GH_PAT}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This experiment has been released! :rocket: This means that it is no longer an experiment and is available in the latest major version of Task. Please see the [experiment workflow documentation](https://taskfile.dev/experiments/workflow) for more information on how we release experiments.' + }) + github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + state: 'closed' + }) + issue-experiment-abandoned: + if: github.event.label.name == format('experiment{0} abandoned', ':') + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + github-token: ${{secrets.GH_PAT}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This experiment has been abandoned. :disappointed: This means that this feature will not be added to Task and any experimental functionality will be removed. Please see the [experiment workflow documentation](https://taskfile.dev/experiments/workflow) for more information on how we release experiments.' + }) + github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + state: 'closed' + }) + issue-experiment-superseded: + if: github.event.label.name == format('experiment{0} superseded', ':') + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + github-token: ${{secrets.GH_PAT}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This experiment has been superseded. :seedling: This means that another experiment has replaced this one. Please see the [experiment workflow documentation](https://taskfile.dev/experiments/workflow) for more information on how we release experiments.' + }) + github.rest.issues.update({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + state: 'closed' + }) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c43879eb8..b962c93ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,10 @@ ## Unreleased -- Only rewrite checksum files in `.task` if the checksum has changed - (#1185, #1194 by @deviantintegral). +- Only rewrite checksum files in `.task` if the checksum has changed (#1185, + #1194 by @deviantintegral). +- Added [experiments documentation](https://taskfile.dev/experiments) to the + website (#1198 by @pd93). ## v3.25.0 - 2023-05-22 @@ -16,7 +18,8 @@ - Fix some errors being unintendedly supressed (#1134 by @clintmod). - Fix a nil pointer error when `version` is omitted from a Taskfile (#1148, #1149 by @pd93). -- Fix duplicate error message when a task does not exists (#1141, #1144 by @pd93). +- Fix duplicate error message when a task does not exists (#1141, #1144 by + @pd93). ## v3.24.0 - 2023-04-15 diff --git a/cmd/release/main.go b/cmd/release/main.go index af339f5a2a..d0bb3ddb7b 100644 --- a/cmd/release/main.go +++ b/cmd/release/main.go @@ -19,7 +19,7 @@ const ( const changelogTemplate = `--- slug: /changelog/ -sidebar_position: 8 +sidebar_position: 9 ---` var ( diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index da4e08b968..42cd1eeb36 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -1,6 +1,6 @@ --- slug: /changelog/ -sidebar_position: 8 +sidebar_position: 9 --- # Changelog diff --git a/docs/docs/community.md b/docs/docs/community.md index d694d548a7..7032b616b0 100644 --- a/docs/docs/community.md +++ b/docs/docs/community.md @@ -1,6 +1,6 @@ --- slug: /community/ -sidebar_position: 9 +sidebar_position: 10 --- # Community diff --git a/docs/docs/contributing.md b/docs/docs/contributing.md index d9589e90de..29b86bc63b 100644 --- a/docs/docs/contributing.md +++ b/docs/docs/contributing.md @@ -1,6 +1,6 @@ --- slug: /contributing/ -sidebar_position: 10 +sidebar_position: 11 --- # Contributing @@ -25,6 +25,11 @@ Studio Code][vscode-task]. there an approach you can take that maintains this compatibility? If not, consider opening an issue first so that API changes can be discussed before you invest your time into a PR. +- **Experiments** - If there is no way to make your change backward compatible + then there is a procedure to introduce breaking changes into minor versions. + We call these "[experiments][experiments]". If you're intending to work on an + experiment, then please read the [experiments workflow][experiments-workflow] + document carefully and submit a proposal first. ## 1. Setup diff --git a/docs/docs/donate.md b/docs/docs/donate.md index d815a6eee4..b039ef9cca 100644 --- a/docs/docs/donate.md +++ b/docs/docs/donate.md @@ -1,6 +1,6 @@ --- slug: /donate/ -sidebar_position: 13 +sidebar_position: 15 --- # Donate diff --git a/docs/docs/experiments/experiments.md b/docs/docs/experiments/experiments.md new file mode 100644 index 0000000000..ff2c69f6bf --- /dev/null +++ b/docs/docs/experiments/experiments.md @@ -0,0 +1,73 @@ +--- +slug: /experiments/ +sidebar_position: 5 +--- + +# Experiments + +:::caution + +All experimental features are subject to breaking changes and/or removal _at any +time_. We strongly recommend that you do not use these features in a production +environment. They are intended for testing and feedback only. + +::: + +In order to allow Task to evolve quickly, we roll out breaking changes to minor +versions behind experimental flags. This allows us to gather feedback on +breaking changes before committing to a major release. This document describes +the current set of experimental features and the deprecated feature that they +are intended to replace. + +You can enable an experimental feature by: + +1. Using the `--x-` flag. This is intended for one-off invocations of + Task to test out experimental features. You can also disable a feature by + specifying a falsy value such as `--x-=false`. +1. Using the `TASK_X_=1` environment variable. This is intended for + permanently enabling experimental features in your environment. + +Flags will always override environment variables. + +## Current Experimental Features and Deprecations + +Each section below details an experiment or deprecation and explains what the +flags/environment variables to enable the experiment are and how the feature's +behavior will change. It will also explain what you need to do to migrate any +existing Taskfiles to the new behavior. + + + +### ![deprecated] Version 2 Schema ([#1197][deprecate-version-2-schema]) + +The Taskfile v2 schema was introduced in March 2018 and replaced by version 3 in +August the following year. Users have had a long time to update and so we feel +that it is time to tidy up the codebase and focus on new functionality instead. + +This notice does not mean that we are immediately removing support for version 2 +schemas. However, support will not be extended to future major releases and we +_strongly recommend_ that anybody still using a version 2 schema upgrades to +version 3 as soon as possible. + +A list of changes between version 2 and version 3 are available in the [Task v3 +Release Notes][version-3-release-notes]. + + +[breaking-change-proposal]: https://github.com/go-task/task/discussions/1191 +[deprecate-version-2-schema]: https://github.com/go-task/task/issues/1197 +[version-3-release-notes]: https://github.com/go-task/task/releases/tag/v3.0.0 +[deprecated]: https://img.shields.io/badge/deprecated-red +[experiment]: https://img.shields.io/badge/experiment-yellow + diff --git a/docs/docs/experiments/workflow.md b/docs/docs/experiments/workflow.md new file mode 100644 index 0000000000..5e1377c02f --- /dev/null +++ b/docs/docs/experiments/workflow.md @@ -0,0 +1,84 @@ +--- +slug: /experiments/workflow/ +--- + +# Workflow + +Experiments are a way for us to test out new features in Task before committing +to them in a major release. Because this concept is built around the idea of +feedback from our community, we have built a workflow for the process of +introducing these changes. This ensures that experiments are given the attention +and time that they need and that we are getting the best possible results out of +them. + +The sections below describe the various stages that an experiment must go +through from its proposal all the way to being released in a major version of +Task. + +## 1. Proposal + +All experimental features start with a proposal in the form of a GitHub issue. +If the maintainers decide that an issue has enough support and is a breaking +change or is complex/controversial enough to require user feedback, then the +issue will be marked with the ![proposal] label. At this point, the issue +becomes a proposal and a period of consultation begins. During this period, we +request that users provide feedback on the proposal and how it might effect +their use of Task. It is up to the discretion of the maintainers to decide how +long this period lasts. + +## 2. Draft + +Once a proposal's consultation ends, a contributor may pick up the work and +begin the initial implementation. Once a PR is opened, the maintainers will +ensure that it meets the requirements for an experimental feature (i.e. flags +are in the right format etc) and merge the feature. Once this code is released, +the status will be updated via the ![draft] label. This indicates that an +implementation is now available for use in a release and the experiment is open +for feedback. + +:::note + +During the draft period, major changes to the implementation may be made based +on the feedback received from users. There are _no stability guarantees_ and +experimental features may be abandoned _at any time_. + +::: + +## 3. Candidate + +Once an acceptable level of consensus has been reached by the community and +feedback/changes are less frequent/significant, the status may be updated via +the ![candidate] label. This indicates that a proposal is _likely_ to accepted +and will enter a period for final comments and minor changes. + +## 4. Stable + +Once a suitable amount of time has passed with no changes or feedback, an +experiment will be given the ![stable] label. At this point, the functionality +will be treated like any other feature in Task and any changes _must_ be +backward compatible. This allows users to migrate to the new functionality +without having to worry about anything breaking in future releases. This +provides the best experience for users migrating to a new major version. + +## 5. Released + +When making a new major release of Task, all experiments marked as ![stable] +will move to ![released] and their behaviors will become the new default in +Task. Experiments in an earlier stage (i.e. not stable) cannot be released and +so will continue to be experiments in the new version. + +## Abandoned / Superseded + +If an experiment is unsuccessful at any point then it will be given the +![abandoned] or ![superseded] labels depending on which is more suitable. These +experiments will be removed from Task. + + +[proposal]: https://img.shields.io/badge/experiment:%20proposal-purple +[draft]: https://img.shields.io/badge/experiment:%20draft-purple +[candidate]: https://img.shields.io/badge/experiment:%20candidate-purple +[stable]: https://img.shields.io/badge/experiment:%20stable-purple +[released]: https://img.shields.io/badge/experiment:%20released-purple +[abandoned]: https://img.shields.io/badge/experiment:%20abandoned-purple +[superseded]: https://img.shields.io/badge/experiment:%20superseded-purple + diff --git a/docs/docs/faq.md b/docs/docs/faq.md index cb37a424b3..db749a48cc 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -1,6 +1,6 @@ --- slug: /faq/ -sidebar_position: 6 +sidebar_position: 7 --- # FAQ diff --git a/docs/docs/integrations.md b/docs/docs/integrations.md index 3ab72a6585..4ca8861aa3 100644 --- a/docs/docs/integrations.md +++ b/docs/docs/integrations.md @@ -1,6 +1,6 @@ --- slug: /integrations/ -sidebar_position: 5 +sidebar_position: 6 --- # Integrations diff --git a/docs/docs/releasing.md b/docs/docs/releasing.md index dc36d1ac6d..ba7bf47a10 100644 --- a/docs/docs/releasing.md +++ b/docs/docs/releasing.md @@ -1,6 +1,6 @@ --- slug: /releasing/ -sidebar_position: 11 +sidebar_position: 13 --- # Releasing diff --git a/docs/docs/styleguide.md b/docs/docs/styleguide.md index b3c77cc07a..fde3ec1d9a 100644 --- a/docs/docs/styleguide.md +++ b/docs/docs/styleguide.md @@ -1,6 +1,6 @@ --- slug: /styleguide/ -sidebar_position: 7 +sidebar_position: 8 --- # Styleguide diff --git a/docs/docs/taskfile_versions.md b/docs/docs/taskfile_versions.md index 5738d6a49d..ca6aa6d87b 100644 --- a/docs/docs/taskfile_versions.md +++ b/docs/docs/taskfile_versions.md @@ -1,6 +1,6 @@ --- slug: /taskfile-versions/ -sidebar_position: 12 +sidebar_position: 14 --- # Taskfile Versions @@ -18,86 +18,122 @@ The `version:` key on Taskfile accepts a semver string, so either `2`, `2.0` or `2.1` features, but if you choose to use `2`, then any `2.x.x` features will be available, but not `3.0.0+`. -## Version 1 +## Version 3 ![latest](https://img.shields.io/badge/latest-brightgreen) -> NOTE: Taskfiles in version 1 are not supported on Task >= v3.0.0 anymore. +These are some major changes done on `v3`: -In the first version of the `Taskfile`, the `version:` key was not available, -because the tasks was in the root of the YAML document. Like this: +- Task's output will now be colored +- Added support for `.env` like files +- Added `label:` setting to task so one can override how the task name appear in + the logs +- A global `method:` was added to allow setting the default method, and Task's + default changed to `checksum` +- Two magic variables were added when using `status:`: `CHECKSUM` and + `TIMESTAMP` which contains, respectively, the md5 checksum and greatest + modification timestamp of the files listed on `sources:` +- Also, the `TASK` variable is always available with the current task name +- CLI variables are always treated as global variables +- Added `dir:` option to `includes` to allow choosing on which directory an + included Taskfile will run: ```yaml -echo: - cmds: - - echo "Hello, World!" +includes: + docs: + taskfile: ./docs + dir: ./docs ``` -The variable priority order was also different: +- Implemented short task syntax. All below syntaxes are equivalent: -1. Call variables -2. Environment -3. Task variables -4. `Taskvars.yml` variables +```yaml +version: '3' -## Version 2.0 +tasks: + print: + cmds: + - echo "Hello, World!" +``` -At version 2, we introduced the `version:` key, to allow us to evolve Task with -new features without breaking existing Taskfiles. The new syntax is as follows: +```yaml +version: '3' + +tasks: + print: + - echo "Hello, World!" +``` ```yaml -version: '2' +version: '3' tasks: - echo: - cmds: - - echo "Hello, World!" + print: echo "Hello, World!" ``` -Version 2 allows you to write global variables directly in the Taskfile, if you -don't want to create a `Taskvars.yml`: +- There was a major refactor on how variables are handled. They're now easier to + understand. The `expansions:` setting was removed as it became unnecessary. + This is the order in which Task will process variables, each level can see the + variables set by the previous one and override those. + - Environment variables + - Global + CLI variables + - Call variables + - Task variables + +## Version 2.6 + +:::caution + +v2 schema support is [deprecated][deprecate-version-2-schema] and will be +removed in a future release. + +::: + +Version 2.6 comes with `preconditions` stanza in tasks. ```yaml version: '2' -vars: - GREETING: Hello, World! - tasks: - greet: + upload_environment: + preconditions: + - test -f .env cmds: - - echo "{{.GREETING}}" + - aws s3 cp .env s3://myenvironment ``` -The variable priority order changed to the following: +Please check the [documentation][includes] -1. Task variables -2. Call variables -3. Taskfile variables -4. Taskvars file variables -5. Environment variables +[output]: usage.md#output-syntax +[ignore_errors]: usage.md#ignore-errors +[includes]: usage.md#including-other-taskfiles -A new global option was added to configure the number of variables expansions -(which default to 2): +## Version 2.2 -```yaml -version: '2' +:::caution -expansions: 3 +v2 schema support is [deprecated][deprecate-version-2-schema] and will be +removed in a future release. -vars: - FOO: foo - BAR: bar - BAZ: baz - FOOBAR: '{{.FOO}}{{.BAR}}' - FOOBARBAZ: '{{.FOOBAR}}{{.BAZ}}' +::: -tasks: - default: - cmds: - - echo "{{.FOOBARBAZ}}" +Version 2.2 comes with a global `includes` options to include other Taskfiles: + +```yaml +version: '2' + +includes: + docs: ./documentation # will look for ./documentation/Taskfile.yml + docker: ./DockerTasks.yml ``` ## Version 2.1 +:::caution + +v2 schema support is [deprecated][deprecate-version-2-schema] and will be +removed in a future release. + +::: + Version 2.1 includes a global `output` option, to allow having more control over how commands output are printed to the console (see [documentation][output] for more info): @@ -134,95 +170,95 @@ tasks: ignore_error: true ``` -## Version 2.2 +## Version 2.0 -Version 2.2 comes with a global `includes` options to include other Taskfiles: +:::caution + +v2 schema support is [deprecated][deprecate-version-2-schema] and will be +removed in a future release. + +::: + +At version 2, we introduced the `version:` key, to allow us to evolve Task with +new features without breaking existing Taskfiles. The new syntax is as follows: ```yaml version: '2' -includes: - docs: ./documentation # will look for ./documentation/Taskfile.yml - docker: ./DockerTasks.yml +tasks: + echo: + cmds: + - echo "Hello, World!" ``` -## Version 2.6 - -Version 2.6 comes with `preconditions` stanza in tasks. +Version 2 allows you to write global variables directly in the Taskfile, if you +don't want to create a `Taskvars.yml`: ```yaml version: '2' +vars: + GREETING: Hello, World! + tasks: - upload_environment: - preconditions: - - test -f .env + greet: cmds: - - aws s3 cp .env s3://myenvironment + - echo "{{.GREETING}}" ``` -Please check the [documentation][includes] - -[output]: usage.md#output-syntax -[ignore_errors]: usage.md#ignore-errors -[includes]: usage.md#including-other-taskfiles - -## Version 3 +The variable priority order changed to the following: -These are some major changes done on `v3`: +1. Task variables +2. Call variables +3. Taskfile variables +4. Taskvars file variables +5. Environment variables -- Task's output will now be colored -- Added support for `.env` like files -- Added `label:` setting to task so one can override how the task name appear in - the logs -- A global `method:` was added to allow setting the default method, and Task's - default changed to `checksum` -- Two magic variables were added when using `status:`: `CHECKSUM` and - `TIMESTAMP` which contains, respectively, the md5 checksum and greatest - modification timestamp of the files listed on `sources:` -- Also, the `TASK` variable is always available with the current task name -- CLI variables are always treated as global variables -- Added `dir:` option to `includes` to allow choosing on which directory an - included Taskfile will run: +A new global option was added to configure the number of variables expansions +(which default to 2): ```yaml -includes: - docs: - taskfile: ./docs - dir: ./docs -``` +version: '2' -- Implemented short task syntax. All below syntaxes are equivalent: +expansions: 3 -```yaml -version: '3' +vars: + FOO: foo + BAR: bar + BAZ: baz + FOOBAR: '{{.FOO}}{{.BAR}}' + FOOBARBAZ: '{{.FOOBAR}}{{.BAZ}}' tasks: - print: + default: cmds: - - echo "Hello, World!" + - echo "{{.FOOBARBAZ}}" ``` -```yaml -version: '3' +## Version 1 -tasks: - print: +:::caution + +v1 schema support was removed in Task >= v3.0.0. + +::: + +In the first version of the `Taskfile`, the `version:` key was not available, +because the tasks was in the root of the YAML document. Like this: + +```yaml +echo: + cmds: - echo "Hello, World!" ``` -```yaml -version: '3' +The variable priority order was also different: -tasks: - print: echo "Hello, World!" -``` +1. Call variables +2. Environment +3. Task variables +4. `Taskvars.yml` variables -- There was a major refactor on how variables are handled. They're now easier to - understand. The `expansions:` setting was removed as it became unnecessary. - This is the order in which Task will process variables, each level can see the - variables set by the previous one and override those. - - Environment variables - - Global + CLI variables - - Call variables - - Task variables + +[deprecate-version-2-schema]: https://github.com/go-task/task/issues/1197 + diff --git a/docs/docs/translate.md b/docs/docs/translate.md index 92b409dc1d..47f39b35a3 100644 --- a/docs/docs/translate.md +++ b/docs/docs/translate.md @@ -1,6 +1,6 @@ --- slug: /translate/ -sidebar_position: 14 +sidebar_position: 12 --- # Translate