iTranslated by AI
Static Link Tool for External Modules
This is a dotnet tool for performing pseudo-static linking.
Using it in GitHub Actions might make it a viable alternative to git submodules.
What it can do
Roughly speaking, it is a tool that adds the following features to xcopy and robocopy:
- Downloading from GitHub or public URLs
- C# script editing capabilities (changing type access range / namespace)
While it includes features specifically for C# scripts, it also supports other file types.
Usage
First, install it from the command line. (.NET SDK 8.0 or higher is required.)
dotnet tool install -g SatorImaging.DotnetTool.StaticImport
Once installed, you can perform copies as follows:
# On Windows, change \ to ^ (can also be done without line breaks)
static-import -o "." -i \
"local-file.cs" \
"github:user@repo/BRANCH_TAG_OR_COMMIT/path/to/file.cs" \
"https://gist.githubusercontent.com/..." \ # Use Raw links for downloads from Gist
"https://inter.net/path/to/file.cs"
You can check other options with
static-import --help.
GitHub Options
You can also download from GitHub repository https: addresses, but using github: allows you to retrieve accurate update timestamps, which helps prevent unnecessary copying.
github:<USER_NAME>@<REPO_NAME>/<REF>/path/to/file.ext
- REF: Branch name, tag, or commit hash
If the environment variable GH_TOKEN or GITHUB_TOKEN is set, it will be used for API access. (This mitigates the rate limit of 60 requests per hour.)
env:
# Common environment variables with GitHub CLI (either one is fine)
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
C# Script Editing Options
When performing static linking (simply copying), you can also edit C# scripts at the same time.
-
--internal- Changes the visibility of all
publictypes tointernal. *Nested types remain unchanged.
- Changes the visibility of all
-
--namespace <NAME>- Changes the namespace to the specified one. *Nested
namespacesyntax remains unchanged. - If the new name ends with
., it is added as a prefix.
- Changes the namespace to the specified one. *Nested
namespace FileScoped; // 👈 Will be changed
namespace Foo.Bar.Baz // 👈 Will be changed
{
namespace Quuuuux // Will not be changed
{
public class MyClass // 👈 Will be changed
{
// Will not be changed
public enum MyEnum { }
public struct MyStruct { }
public record MyRecord { }
public interface IMyInterface { }
}
}
}
Usage in GitHub Actions
Previously, I created an action that sends files from a source to a destination to create a pull request, but it was very tedious as access tokens had to be managed for each source repository.
static-import uses a style where the destination repository gathers the files, allowing you to aggregate files without a token if the source is a public repository. Also, for private repositories, you only need to grant a token to the destination repository.
👇 Sample usage in GitHub Actions
How to Easily and Reliably Create PRs in GitHub Actions
After collecting files with static-import, you probably want to create a PR. Here is how to easily perform the somewhat tedious PR creation process.
First, set up an access token for the GitHub CLI. This configuration is the same as the one used for static-import.
env:
GH_TOKEN: ${{ github.token }}
Next, perform the boilerplate setup for the GitHub CLI.
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
# Configure to automatically track the remote repository upon pushing
git config --global --add --bool push.autoSetupRemote true
The most annoying part is handling conditional branching, such as "if there are files, do this..." or "if this and that happens, do that...". However, if your requirement is simply:
- Create a PR if there are updated files
- Exit without error if there are none
Then you can handle it by utilizing ||.
Even if you research thoroughly to do things the "correct" way, it often fails because of different git versions or other reasons, so this method ends up being the best choice.
git fetch
# If switching to the repository fails, create a new one (-c)
git switch release/${{ inputs.release_ver }} || git switch -c release/${{ inputs.release_ver }}
# Pull from remote (this will fail if newly created, so use || true)
git pull || true
# Repository operations
#git add **/*
# Ensure everything finishes successfully even if a command fails!
git commit -m "Precompiled Assembly for Unity" || true
git push || true
gh pr create -B main --title 'release/${{ inputs.release_ver }}' --body '' || true
Conclusion
I tried using the System.CommandLine 2.0 beta. I think it might be useful when combined with the direct execution of .cs files in .NET 10.0. (Is that the reason for the breaking renewal?)
I actually wanted to have AI create this entire tool, but since my workflow isn't fully established yet, I could only use it to the extent of reducing the effort needed to research Roslyn.
It feels like, "If I had the time to build this..."
That's all. Thank you.
Discussion