GitoxideLabs / gitoxide

An idiomatic, lean, fast & safe pure Rust implementation of Git
Apache License 2.0
8.91k stars 303 forks source link

Release workflow relies on deprecated `set-output` feature #1484

Closed EliahKagan closed 2 months ago

EliahKagan commented 2 months ago

Current behavior 😯

The release.yml workflow uses the unmaintained upload-release-asset action to attach archive files to just-made releases. This action sets step output by writing text to stdout that contains the string ::set-output, which GitHub Actions treats specially.

This old technique is deprecated. GitHub hopes eventually to remove it, due to the security problems entailed by setting output when displaying untrusted data that may contain the string ::set-output, though they have deferred doing so since this and related features remain in somewhat wide use. If and when it is eventually removed, workflows that use it, even indirectly as in release.yml, will break.

Currently, this accounts for many of the warnings issued when the release workflow runs. This is from the most recent run as of this writing, which was prior to the recent changes in #1475 and #1479, but those changes do not affect this behavior. The warnings about this can be seen on a summary page for any run of the workflow, and say:

The set-output command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

The other warnings are also due to the use of the unmaintained upload-release-asset action. They are about a mismatch between the version of Node.js that the action was written for, and the version it is run on. It is a Node 12 action, but this Node version has been unsupported for a long time, and GitHub no longer provides it on GHA runners, both for security and general maintenance reasons. As a result, it runs on Node 16.

The following actions uses node12 which is deprecated and will be forced to run on node16: actions/upload-release-asset@v1.0.2. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/

It has been doing so for a while and works, so it is unlikely to break due to running on Node 16. But Node 16 is also now unsupported for a long time, and GitHub shall soon no longer provide it; it will run automatically on Node 20 sometime soon. This is detailed in GitHub Actions: Transitioning from Node 16 to Node 20. My guess is that this will not break it, but it is hard to be completely sure. So this is a second reason to replace uses of that action.

Expected behavior 🤔

There is not really a strong expectation, but ideally there would be nothing in the release workflow that could plausibly cause breakage in the foreseeable future, and accordingly no warnings about such conditions.

Git behavior

Git doesn't have corresponding workflows

To the best my of knowledge, Git does not use GitHub Actions for releasing, and neither does Git for Windows. However, they do use GitHub Actions for other purposes. It does not appear that their workflows issue such warnings, and a quick glance at the actions listed as dependencies on the Insights tab seems to confirm this. I didn't carefully check, though, since the relevance of workflows that don't point the way to what gitoxide could use is rather slight.

But ripgrep does

In contrast, the ripgrep release workflow is very relevant, because the gitoxide release workflow is based on it (https://github.com/Byron/gitoxide/pull/1239#pullrequestreview-1809363846, https://github.com/Byron/gitoxide/issues/1472#issuecomment-2254244666).

Over time, the ripgrep workflow has been revised significantly, and one of the changes has been to eliminate the use of that action, as well as some others, by switching to using the gh command instead, which is preinstalled on the runners.

This was done in https://github.com/BurntSushi/ripgrep/commit/c9584b035b19244e370a50fd872a3ae2039e2931 (https://github.com/BurntSushi/ripgrep/pull/2554), and for basically the same reason (https://github.com/BurntSushi/ripgrep/pull/2360), though gitoxide already does not use the create-release mentioned there. gitoxide uses the release-action action instead since 43ce9f5, which is fine to use, though also natural to replace by gh at the same time.

Using gh for everything applicable would simplify things significantly (though, as noted below, I would probably be doing it together with other changes that add complexity elsewhere). Only the version, and not the URL, would have to be passed between dependent jobs. It would also be easier to understand the relationship between the operations on the GitHub release if they are all done in similar ways, so using the gh command for some of them but not others would likely be less clear then using it for all of them.

I plan to include this change in the same PR that adds builds of universal binaries, for the currently one remaining task in #1478. They make sense to do at the same time because, as planned in https://github.com/Byron/gitoxide/issues/1478#issuecomment-2257584083, this involves adding at least one more kind of operation on the release: downloading the aarch64 and x86_64 builds from the GitHub release in order to extract their binaries and use them to make the Universal 2 binary. Downloading assets from a release is also easy to do with gh.

A possible alternative solution is to use a different action in place of upload-release-asset for the same functionality. I don't think there is a drop-in replacement, but its readme suggests action-gh-release. This is a much broader action, rather than being specific to uploading assets. This would probably be okay, but it's not the solution I favor, and I mention it only for completeness or in case there are disadvantages of using gh here that I am not aware of.

Steps to reproduce 🕹

Go to any recent run of any job of the release workflow and click Summary near the upper left of the page to examine the summary for the entire workflow run. Then scroll down to see all warnings from all jobs in the workflow. (They are much easier to spot there than when examining individual workflows, where it would usually be necessary to expand specific steps.)

Alternatively, just follow the links above to the most recent one.