[{"data":1,"prerenderedAt":564},["ShallowReactive",2],{"NoscriptNav_XrRK2e2e8meJ0jKVGkb5ULGQDVi3UiFQ9nupAr7Yns":3,"\u002Ftools\u002Fgit-pkgs-actions":8},["Island",4],{"key":5,"result":6},"NoscriptNav_XrRK2e2e8meJ0jKVGkb5ULGQDVi3UiFQ9nupAr7Yns",{"head":7},{},{"id":9,"title":10,"authors":11,"body":13,"canonicalUrl":551,"canonicalWebsiteName":552,"category":553,"date":554,"description":555,"extension":556,"featured":557,"fullWidthLayout":557,"image":558,"imageAlt":558,"location":558,"meta":559,"metaImage":558,"navigation":103,"path":560,"seo":561,"stem":562,"venue":558,"venueUrl":558,"__hash__":563},"tools\u002Ftools\u002Fgit-pkgs-actions.md","git-pkgs\u002Factions",[12],"andrew",{"type":14,"value":15,"toc":545},"minimark",[16,28,40,129,132,137,150,184,195,199,231,234,238,270,285,289,498,513,528,541],[17,18,19,20,27],"p",{},"Until now ",[21,22,26],"a",{"href":23,"rel":24},"https:\u002F\u002Fgithub.com\u002Fgit-pkgs\u002Fgit-pkgs",[25],"nofollow","git-pkgs"," has been a local tool, you run it in your terminal to query dependency history, scan for vulnerabilities, check licenses. Getting it into CI meant downloading the binary yourself, initializing the database, and wiring up whatever checks you wanted by hand.",[17,29,30,34,35,39],{},[21,31,10],{"href":32,"rel":33},"https:\u002F\u002Fgithub.com\u002Fgit-pkgs\u002Factions",[25]," is a set of reusable GitHub Actions that handle all of that. A ",[36,37,38],"code",{},"setup"," action downloads the binary and initializes the database, and the rest build on top of it. A dependency diff on pull requests is three lines of YAML:",[41,42,47],"pre",{"className":43,"code":44,"language":45,"meta":46,"style":46},"language-yaml shiki shiki-themes github-light github-dark","steps:\n  - uses: actions\u002Fcheckout@v4\n    with:\n      fetch-depth: 0\n\n  - uses: git-pkgs\u002Factions\u002Fsetup@v1\n  - uses: git-pkgs\u002Factions\u002Fdiff@v1\n","yaml","",[36,48,49,62,78,86,98,105,117],{"__ignoreMap":46},[50,51,54,58],"span",{"class":52,"line":53},"line",1,[50,55,57],{"class":56},"s9eBZ","steps",[50,59,61],{"class":60},"sVt8B",":\n",[50,63,65,68,71,74],{"class":52,"line":64},2,[50,66,67],{"class":60},"  - ",[50,69,70],{"class":56},"uses",[50,72,73],{"class":60},": ",[50,75,77],{"class":76},"sZZnC","actions\u002Fcheckout@v4\n",[50,79,81,84],{"class":52,"line":80},3,[50,82,83],{"class":56},"    with",[50,85,61],{"class":60},[50,87,89,92,94],{"class":52,"line":88},4,[50,90,91],{"class":56},"      fetch-depth",[50,93,73],{"class":60},[50,95,97],{"class":96},"sj4cs","0\n",[50,99,101],{"class":52,"line":100},5,[50,102,104],{"emptyLinePlaceholder":103},true,"\n",[50,106,108,110,112,114],{"class":52,"line":107},6,[50,109,67],{"class":60},[50,111,70],{"class":56},[50,113,73],{"class":60},[50,115,116],{"class":76},"git-pkgs\u002Factions\u002Fsetup@v1\n",[50,118,120,122,124,126],{"class":52,"line":119},7,[50,121,67],{"class":60},[50,123,70],{"class":56},[50,125,73],{"class":60},[50,127,128],{"class":76},"git-pkgs\u002Factions\u002Fdiff@v1\n",[17,130,131],{},"That posts a comment on the PR listing every dependency that was added, removed, or changed, and updates the same comment on subsequent pushes rather than creating a new one.",[133,134,136],"h3",{"id":135},"vulnerabilities","Vulnerabilities",[17,138,139,140,143,144,149],{},"The ",[36,141,142],{},"vulns"," action syncs against the ",[21,145,148],{"href":146,"rel":147},"https:\u002F\u002Fosv.dev",[25],"OSV database"," and can fail the build above a severity threshold:",[41,151,153],{"className":43,"code":152,"language":45,"meta":46,"style":46},"- uses: git-pkgs\u002Factions\u002Fvulns@v1\n  with:\n    severity: \"high\"\n",[36,154,155,167,174],{"__ignoreMap":46},[50,156,157,160,162,164],{"class":52,"line":53},[50,158,159],{"class":60},"- ",[50,161,70],{"class":56},[50,163,73],{"class":60},[50,165,166],{"class":76},"git-pkgs\u002Factions\u002Fvulns@v1\n",[50,168,169,172],{"class":52,"line":64},[50,170,171],{"class":56},"  with",[50,173,61],{"class":60},[50,175,176,179,181],{"class":52,"line":80},[50,177,178],{"class":56},"    severity",[50,180,73],{"class":60},[50,182,183],{"class":76},"\"high\"\n",[17,185,186,187,190,191,194],{},"Without ",[36,188,189],{},"severity"," it reports findings but doesn't block, which is a reasonable way to start before making it a hard gate. Setting ",[36,192,193],{},"sarif: \"true\""," uploads results to GitHub Advanced Security so vulnerability alerts show up alongside CodeQL in the Security tab.",[133,196,198],{"id":197},"licenses","Licenses",[41,200,202],{"className":43,"code":201,"language":45,"meta":46,"style":46},"- uses: git-pkgs\u002Factions\u002Flicenses@v1\n  with:\n    allow: \"MIT,Apache-2.0,BSD-2-Clause,BSD-3-Clause,ISC\"\n",[36,203,204,215,221],{"__ignoreMap":46},[50,205,206,208,210,212],{"class":52,"line":53},[50,207,159],{"class":60},[50,209,70],{"class":56},[50,211,73],{"class":60},[50,213,214],{"class":76},"git-pkgs\u002Factions\u002Flicenses@v1\n",[50,216,217,219],{"class":52,"line":64},[50,218,171],{"class":56},[50,220,61],{"class":60},[50,222,223,226,228],{"class":52,"line":80},[50,224,225],{"class":56},"    allow",[50,227,73],{"class":60},[50,229,230],{"class":76},"\"MIT,Apache-2.0,BSD-2-Clause,BSD-3-Clause,ISC\"\n",[17,232,233],{},"An allow list permits only those licenses and rejects everything else. You can use a deny list instead if you only want to block a few specific licenses like GPL-3.0 or AGPL-3.0 while accepting the rest. Either way, the \"can we use this license\" conversation happens at PR time rather than after something ships.",[133,235,237],{"id":236},"sboms","SBOMs",[41,239,241],{"className":43,"code":240,"language":45,"meta":46,"style":46},"- uses: git-pkgs\u002Factions\u002Fsbom@v1\n  with:\n    format: \"cyclonedx\"\n",[36,242,243,254,260],{"__ignoreMap":46},[50,244,245,247,249,251],{"class":52,"line":53},[50,246,159],{"class":60},[50,248,70],{"class":56},[50,250,73],{"class":60},[50,252,253],{"class":76},"git-pkgs\u002Factions\u002Fsbom@v1\n",[50,255,256,258],{"class":52,"line":64},[50,257,171],{"class":56},[50,259,61],{"class":60},[50,261,262,265,267],{"class":52,"line":80},[50,263,264],{"class":56},"    format",[50,266,73],{"class":60},[50,268,269],{"class":76},"\"cyclonedx\"\n",[17,271,272,273,278,279,284],{},"Generates a ",[21,274,277],{"href":275,"rel":276},"https:\u002F\u002Fcyclonedx.org\u002F",[25],"CycloneDX"," or ",[21,280,283],{"href":281,"rel":282},"https:\u002F\u002Fspdx.dev\u002F",[25],"SPDX"," Software Bill of Materials and uploads it as a workflow artifact. You can also disable the upload and attach the file to a GitHub release instead, which is what I do for git-pkgs itself.",[133,286,288],{"id":287},"all-together","All together",[41,290,292],{"className":43,"code":291,"language":45,"meta":46,"style":46},"name: Dependencies\non: pull_request\n\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n        with:\n          fetch-depth: 0\n\n      - uses: git-pkgs\u002Factions\u002Fsetup@v1\n      - uses: git-pkgs\u002Factions\u002Fdiff@v1\n      - uses: git-pkgs\u002Factions\u002Fvulns@v1\n        with:\n          severity: \"high\"\n      - uses: git-pkgs\u002Factions\u002Flicenses@v1\n        with:\n          deny: \"GPL-3.0-only,AGPL-3.0-only\"\n",[36,293,294,304,314,318,325,335,345,349,357,365,376,384,396,404,414,419,430,441,452,459,469,480,487],{"__ignoreMap":46},[50,295,296,299,301],{"class":52,"line":53},[50,297,298],{"class":56},"name",[50,300,73],{"class":60},[50,302,303],{"class":76},"Dependencies\n",[50,305,306,309,311],{"class":52,"line":64},[50,307,308],{"class":96},"on",[50,310,73],{"class":60},[50,312,313],{"class":76},"pull_request\n",[50,315,316],{"class":52,"line":80},[50,317,104],{"emptyLinePlaceholder":103},[50,319,320,323],{"class":52,"line":88},[50,321,322],{"class":56},"permissions",[50,324,61],{"class":60},[50,326,327,330,332],{"class":52,"line":100},[50,328,329],{"class":56},"  contents",[50,331,73],{"class":60},[50,333,334],{"class":76},"read\n",[50,336,337,340,342],{"class":52,"line":107},[50,338,339],{"class":56},"  pull-requests",[50,341,73],{"class":60},[50,343,344],{"class":76},"write\n",[50,346,347],{"class":52,"line":119},[50,348,104],{"emptyLinePlaceholder":103},[50,350,352,355],{"class":52,"line":351},8,[50,353,354],{"class":56},"jobs",[50,356,61],{"class":60},[50,358,360,363],{"class":52,"line":359},9,[50,361,362],{"class":56},"  check",[50,364,61],{"class":60},[50,366,368,371,373],{"class":52,"line":367},10,[50,369,370],{"class":56},"    runs-on",[50,372,73],{"class":60},[50,374,375],{"class":76},"ubuntu-latest\n",[50,377,379,382],{"class":52,"line":378},11,[50,380,381],{"class":56},"    steps",[50,383,61],{"class":60},[50,385,387,390,392,394],{"class":52,"line":386},12,[50,388,389],{"class":60},"      - ",[50,391,70],{"class":56},[50,393,73],{"class":60},[50,395,77],{"class":76},[50,397,399,402],{"class":52,"line":398},13,[50,400,401],{"class":56},"        with",[50,403,61],{"class":60},[50,405,407,410,412],{"class":52,"line":406},14,[50,408,409],{"class":56},"          fetch-depth",[50,411,73],{"class":60},[50,413,97],{"class":96},[50,415,417],{"class":52,"line":416},15,[50,418,104],{"emptyLinePlaceholder":103},[50,420,422,424,426,428],{"class":52,"line":421},16,[50,423,389],{"class":60},[50,425,70],{"class":56},[50,427,73],{"class":60},[50,429,116],{"class":76},[50,431,433,435,437,439],{"class":52,"line":432},17,[50,434,389],{"class":60},[50,436,70],{"class":56},[50,438,73],{"class":60},[50,440,128],{"class":76},[50,442,444,446,448,450],{"class":52,"line":443},18,[50,445,389],{"class":60},[50,447,70],{"class":56},[50,449,73],{"class":60},[50,451,166],{"class":76},[50,453,455,457],{"class":52,"line":454},19,[50,456,401],{"class":56},[50,458,61],{"class":60},[50,460,462,465,467],{"class":52,"line":461},20,[50,463,464],{"class":56},"          severity",[50,466,73],{"class":60},[50,468,183],{"class":76},[50,470,472,474,476,478],{"class":52,"line":471},21,[50,473,389],{"class":60},[50,475,70],{"class":56},[50,477,73],{"class":60},[50,479,214],{"class":76},[50,481,483,485],{"class":52,"line":482},22,[50,484,401],{"class":56},[50,486,61],{"class":60},[50,488,490,493,495],{"class":52,"line":489},23,[50,491,492],{"class":56},"          deny",[50,494,73],{"class":60},[50,496,497],{"class":76},"\"GPL-3.0-only,AGPL-3.0-only\"\n",[17,499,139,500,502,503,506,507,512],{},[36,501,38],{}," action runs ",[36,504,505],{},"git-pkgs init"," once and the other steps share the same database. All the actions are composite -- shell scripts, no Node.js or Docker -- and the repo passes ",[21,508,511],{"href":509,"rel":510},"https:\u002F\u002Fgithub.com\u002Fzizmorcore\u002Fzizmor",[25],"zizmor"," in pedantic mode with inputs going through environment variables, action refs pinned by SHA, and credentials not persisted.",[17,514,515,516,521,522,527],{},"There's a lot git-pkgs can do that doesn't have an action yet: integrity drift detection, outdated dependency reports, enforcing package policy through notes. I'm curious what would actually be useful in practice, so if you have ideas or want something specific, open an issue on the ",[21,517,520],{"href":518,"rel":519},"https:\u002F\u002Fgithub.com\u002Fgit-pkgs\u002Factions\u002Fissues",[25],"actions repo"," or find me on ",[21,523,526],{"href":524,"rel":525},"https:\u002F\u002Fmastodon.social\u002F@andrewnez",[25],"Mastodon",".",[529,530,533,534],"div",{"className":531},[532],"page-items","\n    ",[21,535,540],{"className":536,"href":32,"target":539},[537,538],"button","button--arrow","_blank","\n        Go to repository\n    ",[542,543,544],"style",{},"html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":46,"searchDepth":64,"depth":64,"links":546},[547,548,549,550],{"id":135,"depth":80,"text":136},{"id":197,"depth":80,"text":198},{"id":236,"depth":80,"text":237},{"id":287,"depth":80,"text":288},"https:\u002F\u002Fnesbitt.io\u002F2026\u002F03\u002F11\u002Fgit-pkgs-actions","nesbitt.io","software-supply-chains","2026-03-11","How to add git-pkgs to your GitHub Actions workflows.","md",false,null,{},"\u002Ftools\u002Fgit-pkgs-actions",{"title":10,"description":555},"tools\u002Fgit-pkgs-actions","eVyGkBUervobnzXTh7cHPUiRCsrItiDdA3h2Os8eJE0",1780596103439]