{"id":47640789,"url":"https://github.com/duckduckstudio/pinaction","last_synced_at":"2026-06-29T00:00:22.966Z","repository":{"id":346318663,"uuid":"1189357594","full_name":"DuckDuckStudio/PinAction","owner":"DuckDuckStudio","description":"Pin workflow dependency versions to full-length hashes.","archived":false,"fork":false,"pushed_at":"2026-06-16T03:22:29.000Z","size":22256,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-16T05:04:14.921Z","etag":null,"topics":["actions","console-application","csharp","dependency-pinning","workflow"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DuckDuckStudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE.md","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-23T08:36:55.000Z","updated_at":"2026-06-16T03:22:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"f8f31bab-ba0d-4cbb-b902-73a3750f82b4","html_url":"https://github.com/DuckDuckStudio/PinAction","commit_stats":null,"previous_names":["duckduckstudio/pinaction"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/DuckDuckStudio/PinAction","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DuckDuckStudio%2FPinAction","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DuckDuckStudio%2FPinAction/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DuckDuckStudio%2FPinAction/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DuckDuckStudio%2FPinAction/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DuckDuckStudio","download_url":"https://codeload.github.com/DuckDuckStudio/PinAction/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DuckDuckStudio%2FPinAction/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34907985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["actions","console-application","csharp","dependency-pinning","workflow"],"created_at":"2026-04-02T00:53:14.588Z","updated_at":"2026-06-29T00:00:22.959Z","avatar_url":"https://github.com/DuckDuckStudio.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pin Action\n\n\u003e \u003cp style=\"text-align: center\"\u003e\u003ca href=\"README.zh-CN.md\"\u003e简体中文\u003c/a\u003e\u003c/p\u003e\n\nPin workflow dependency versions to full-length hashes.  \n\n![Example use.](example.gif)\n\n## Install\n### Windows\n\n[When the pull request for new version is published](https://github.com/microsoft/winget-pkgs/issues?q=type%3Apr%20author%3ADuckDuckStudio%20%22DuckStudio.PinAction%22), you can install it via winget:  \n\n```shell\nwinget install --id DuckStudio.PinAction -s winget -e\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eLinux\u003c/summary\u003e\n\n### Linux\n\n\u003e I use [WSL2 Ubuntu](https://ubuntu.com/desktop/wsl) + [fish shell](https://fishshell.com/) + [bash](http://www.gnu.org/software/bash).  \n\u003e You can use ANY editor you like, not just limited to [nano](https://www.nano-editor.org/).  \n\u003e Before continuing, please [install the .NET 10 SDK](https://learn.microsoft.com/zh-cn/dotnet/core/install/linux).\n\n#### Clone repository\n\n```shell\ngit clone https://github.com/DuckDuckStudio/PinAction.git # Add the \"-b \u003cversion\u003e\" parameter to specify the version\ncd PinAction/\n```\n\n#### Compiles Pin Action\n\n\u003e [!TIP]  \n\u003e You DON'T necessarily have to strictly follow the examples given here; you can refer to the [`dotnet publish` command documentation](https://learn.microsoft.com/zh-cn/dotnet/core/tools/dotnet-publish) to combine new command.\n\nThe example here uses the Release build configuration, specifying the target operating system as Linux, single file, and self-contained runtime.\n\n```shell\ndotnet publish PinAction --configuration Release --os linux -p:PublishSingleFile=true --self-contained\n\n# For those who like to use lowercase ...\nmv \"PinAction/bin/Release/net10.0/linux-x64/publish/PinAction\" \"PinAction/bin/Release/net10.0/linux-x64/publish/pinaction\"\n```\n\n#### Add to PATH\n\n\u003e Please replace the path in the code with the path to your actual publish folder.  \n\nFor fish:\n```shell\nnano ~/.config/fish/config.fish\n# Add the following code\n# set -gx PATH \"/path/to/repo/PinAction/PinAction/bin/Release/net10.0/linux-x64/publish/\" $PATH\n```\n\nFor bash:\n```bash\nnano ~/.bashrc\n# Add the following code\n# export PATH=\"/path/to/repo/PinAction/PinAction/bin/Release/net10.0/linux-x64/publish/:$PATH\"\n```\n\nThen use the `source` command to reload the configuration.\n\n#### Add fish shell auto-completion\n\n\u003e `complete` command documentation: https://fishshell.com/docs/current/cmds/complete.html\n\n```shell\ntouch ~/.config/fish/completions/pinaction.fish\nnano ~/.config/fish/completions/pinaction.fish\n```\n\nAdd the following content:\n\n\u003e [!NOTE]  \n\u003e If you changed the command to all lowercase earlier, please also change the command here to lowercase.\n\n```shell\n# DuckStudio.PinAction\n# https://github.com/DuckDuckStudio/PinAction/blob/main/README.zh-CN.md\n\n# General Commands (use \"--xxx\" style, for other aliases see \"pinaction --help\")\ncomplete -c PinAction -l help      -d \"显示帮助信息\"\ncomplete -c PinAction -l version   -d \"显示版本号\"\ncomplete -c PinAction -l license   -d \"显示许可信息\"\n```\n\n\u003c/details\u003e\n\n## Usage\n\n```shell\npinaction \"\u003cfile or directory\u003e\"\n```\n\nYou can pass multiple files or directories at once.  \nFor directories, it will recursively look for `.yaml` or `.yml` files within.  \n\nRun `pinaction --help` for more help information.\n\n## Q \u0026 A\n### Does it support using a GitHub Token?\n\nI think it will when I learned how to read and store the Token in C#.  \nCurrently it doesn't, but you can hardcode it in the source code.\n\n### Can it skip some workflows?\n\nPlease modify the code, there are an example in the code.\n\n### Why we need pin the version to the full-length hash?\n\nThis is [a practice recommended by GitHub](https://docs.github.com/en/actions/reference/security/secure-use#using-third-party-actions), and is [considered mandatory](https://github.blog/changelog/2025-08-15-github-actions-policy-now-supports-blocking-and-sha-pinning-actions/) in some projects.  \nIf your workflow dependency do not have [Immutable releases](https://docs.github.com/en/code-security/concepts/supply-chain-security/immutable-releases) enabled, your workflow may be affected if an upstream dependency modifies the same version again.  \nPinning the version to the full-length hash ensures your workflow always uses the same code, even if the upstream dependency modifies the same version.\n\n### What is the \"full-length hash\"?\n\nIt is the Git commit hash corresponding to the specified workflow version (tag).\n\n### How does this program replace the content?\n\nI took the easy route — instead of parsing YAML, I simply split lines containing `uses:` and applied regex after a few `.Split()` operations.  \nFor details, see the `PinActionHash` method in the source code.\n\n### Why doesn't it have an icon?\n\nBecause I can't draw. After an hour of thinking, [我已急哭](https://baike.baidu.com/item/你已急哭).\n\n## License\n\nThis program is licensed under the [MIT License](https://github.com/DuckDuckStudio/PinAction/blob/main/LICENSE.txt).\n\n### Dependencies\n\nThis program would not have been possible without these projects.  \nThank you to the open-source community!\n\n| Package | License |\n|-----|-----|\n| [Octokit](https://www.nuget.org/packages/Octokit/) | MIT License |\n| [DuckStudio.CatFood](https://www.nuget.org/packages/DuckStudio.CatFood) | Apache License 2.0 |\n| [Spectre.Console](https://www.nuget.org/packages/Spectre.Console/) | MIT License |\n\nFor the license files related to these dependencies, please see [NOTICE.md](https://github.com/DuckDuckStudio/PinAction/blob/main/NOTICE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduckduckstudio%2Fpinaction","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduckduckstudio%2Fpinaction","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduckduckstudio%2Fpinaction/lists"}