99 Commits

Author SHA1 Message Date
35168619ff Fix conflicts with main 2024-06-06 10:54:15 -07:00
4e3e886d7a Add missing env vars to inputs 2024-06-06 10:51:46 -07:00
ed0fe829d8 Merge pull request #115 from detsys-pr-bot/detsys-ts-update-bc45b6c0a6318ae30192c4bf23a73dc879bdb632
Update `detsys-ts`:
2024-06-05 16:19:34 -07:00
278b2c0e02 Merge pull request #114 from detsys-pr-bot/detsys-ts-update-515d00bc192ae4460e2122572ebc24020c58ea95
Update detsys-ts: Merge pull request #51 from DeterminateSystems/add-missing-actions-to-update-matrix

Add missing Actions to update matrix
2024-06-05 15:48:14 -07:00
1b00b724a5 Regenerate dist 2024-06-05 15:46:52 -07:00
23e86b41e2 Merge pull request #116 from detsys-pr-bot/detsys-ts-update-856a75af22949b76e23f6e54a1b4d27d8816cea4
Update `detsys-ts`: Merge pull request #113 from DeterminateSystems/update-detsys-ts-status-page
2024-06-05 18:06:07 -04:00
b8b46eb7bb Update detsys-ts for: Merge pull request #113 from DeterminateSystems/update-detsys-ts-status-page (856a75af22949b76e23f6e54a1b4d27d8816cea4) 2024-06-05 21:59:53 +00:00
50c97e1435 Update detsys-ts for: ` (bc45b6c0a6318ae30192c4bf23a73dc879bdb632`) 2024-06-05 21:32:11 +00:00
d777dd2ba4 Update detsys-ts for: Merge pull request #51 from DeterminateSystems/add-missing-actions-to-update-matrix
Add missing Actions to update matrix (515d00bc192ae4460e2122572ebc24020c58ea95)
2024-06-05 21:06:52 +00:00
0829421b88 Initial version of PR body rendering 2024-06-04 09:19:35 -07:00
8c5e8043f8 More test cases: 2024-06-04 08:44:31 -07:00
09b0ac8cd3 Enable supplying a commit message template 2024-06-04 08:28:12 -07:00
d3aa136776 Provide pr-body as output from step 2024-06-03 14:32:30 -07:00
5d674d8347 Fix formatting 2024-06-03 14:20:34 -07:00
3f84616103 Remove test subflake 2024-06-03 14:18:58 -07:00
cbee267f6f Fix merge conflicts with main 2024-06-03 13:44:53 -07:00
bba6a453b7 Merge pull request #113 from DeterminateSystems/update-detsys-ts-status-page
Update detsys-ts (status page changes)
2024-06-03 09:18:41 -07:00
aecc58b9ac Update detsys-ts (status page changes) 2024-06-03 09:12:51 -07:00
41c8f7e1b5 Merge pull request #112 from DeterminateSystems/srv
Update detsys-ts for srv
2024-05-31 12:05:22 -04:00
be77a56766 eslint stricter 2024-05-31 11:40:33 -04:00
d98ea6576b Update detsys-ts for srv 2024-05-31 11:34:46 -04:00
2b0d863d87 Merge pull request #111 from DeterminateSystems/update-detsys-ts
Update detsys-ts
2024-05-29 15:20:23 -03:00
559c3e249c Update detsys-ts 2024-05-29 15:18:32 -03:00
5d30a7794a Make a single dir a special case 2024-05-23 23:39:14 -03:00
dccc3175bf Update detsys-ts 2024-05-23 19:19:07 -03:00
c16b76233e Provide improved input handling 2024-05-23 16:09:06 -03:00
b5a9000c3f Check for flake-dirs clash with inputs 2024-05-23 15:55:25 -03:00
b6aab91cde Improve flake-dirs handling logic 2024-05-23 15:48:19 -03:00
c7eb3f32c9 Fix input validation 2024-05-23 15:42:03 -03:00
0c1dd1090d Add CI test 2024-05-23 15:37:34 -03:00
eb897bb16b Add README.md example 2024-05-23 15:34:32 -03:00
1127ba41bd Check that each directory is a valid flake 2024-05-23 15:33:00 -03:00
f5dab0ead5 Rework input handling 2024-05-23 15:19:56 -03:00
6a1287939f Add flake-dirs input 2024-05-23 15:16:12 -03:00
222f041780 Merge pull request #108 from DeterminateSystems/strict-mode-env-var
Add environment variable for strict mode input
2024-05-23 12:26:35 -03:00
0e2a61b1f3 Add environment variable for strict mode input 2024-05-23 12:23:56 -03:00
ede634b2c8 Merge pull request #107 from DeterminateSystems/strict-mode-not-required
Make strict mode input not required
2024-05-23 12:05:47 -03:00
7a7f13f9b5 Make strict mode input not required 2024-05-23 12:03:54 -03:00
e0fe1f8e46 Merge pull request #105 from DeterminateSystems/detsys-ts-update
Update detsys-ts
2024-05-22 20:27:21 -03:00
7ce3b51a1d Update detsys-ts 2024-05-22 15:40:01 -03:00
4f21d96ab3 Merge pull request #103 from DeterminateSystems/space-sep
Split flake inputs on spaces instead of commas
2024-05-09 18:14:58 -04:00
165ae6e270 space-sep'd inputs 2024-05-09 18:13:24 -04:00
bcabaab2f1 Merge pull request #101 from DeterminateSystems/detsys-ts
Convert the Action into TypeScript
2024-05-09 15:50:34 -04:00
406a429015 Regenerate 2024-05-09 15:48:13 -04:00
28eac596e7 nits on the nits 2024-05-09 15:47:03 -04:00
da64c8c904 nits 2024-05-09 15:45:38 -04:00
3fa85bcf4c nit: run line 2024-05-09 15:44:43 -04:00
d021735a89 space separated options 2024-05-09 15:35:58 -04:00
d978837d43 Expose all inputs 2024-05-09 15:35:53 -04:00
fc5dacd10b Use nix flake update if no inputs are specified 2024-05-09 14:15:38 -04:00
7352b7f36b lockfile-summary, d'oh 2024-05-07 23:03:21 -04:00
6d82bce8ec Update detsys-ts 2024-05-07 23:03:12 -04:00
8363f28293 Call the node action instead directly 2024-05-07 23:02:56 -04:00
1752965d0b Don't cd separately 2024-05-06 16:13:34 -04:00
21663d562d Rename workflow 2024-04-29 10:15:25 -03:00
6318aa12c1 Remove now-unnecessary shellcheck check 2024-04-26 14:23:24 -03:00
239b4c9810 Add JS-specific bits to Actions 2024-04-26 14:19:53 -03:00
539b7a6481 Remove Bash script and do more TS streamlining 2024-04-26 12:10:07 -03:00
dde5487502 Finish initial rework into TS 2024-04-26 11:55:19 -03:00
502daa7e5e Construct Nix command 2024-04-21 19:50:32 -03:00
b1f8684b21 Update Nix shell and add envrc 2024-04-21 19:42:23 -03:00
cf6776dfd1 Add initial JS setup 2024-04-21 19:17:03 -03:00
cc5f064749 Update README.md to use actions/checkout@v4 2024-04-08 09:21:10 -07:00
a3ccb8f597 Update pedrolamas/handlebars-action to 2.4.0 2024-02-29 07:07:00 -08:00
56b3507bfe Update DamianReeves/write-file-action to v1.3 2024-02-28 15:06:00 -08:00
70d01ca550 build(deps): bump pedrolamas/handlebars-action from 2.2.0 to 2.3.0
Bumps [pedrolamas/handlebars-action](https://github.com/pedrolamas/handlebars-action) from 2.2.0 to 2.3.0.
- [Release notes](https://github.com/pedrolamas/handlebars-action/releases)
- [Commits](https://github.com/pedrolamas/handlebars-action/compare/v2.2.0...v2.3.0)

---
updated-dependencies:
- dependency-name: pedrolamas/handlebars-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-28 14:55:32 -08:00
96c74d26ed build(deps): bump actions/checkout from 2 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-28 14:55:13 -08:00
0631a12d9a build(deps): bump crazy-max/ghaction-import-gpg from 5 to 6
Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 5 to 6.
- [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases)
- [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/v5...v6)

---
updated-dependencies:
- dependency-name: crazy-max/ghaction-import-gpg
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-28 14:54:51 -08:00
a72d3c5880 update peter-evans/create-pull-request to v6 2024-02-28 14:54:06 -08:00
e98d4358e3 Bump peter-evans/create-pull-request to v5 2023-10-10 13:22:51 -07:00
d374cc7d4a Mechanical migration to FlakeHub 2023-10-10 13:21:55 -07:00
af80b95b83 Update action versions to main.
Folks can pin to recent versions if they choose.
2023-09-15 21:58:32 -04:00
da2fd6f256 Update action.yml 2023-08-24 00:12:15 -04:00
fd510d25c0 Merge pull request #78 from DeterminateSystems/DS-970
DS-970: Add Magic Nix Cache and other workflow changes
2023-07-21 09:21:51 -07:00
1a057b79b1 ci: clearly name steps in update.yml 2023-07-21 15:52:27 +01:00
51e1459968 DS-970: Add Magic Nix Cache and other workflow changes
An assortment of GitHub Workflow changes, potentially including:

- Enable DeterminateSystems/magic-nix-cache-action@main
- Reference all DeterminateSystems actions via @main
- Make update.yaml consistent across repos
- Remove unnecessary github-token: from nix-installer-action
- Update actions/checkout@v2 to actions/checkout@v3
2023-07-14 10:21:02 +01:00
4fbf969957 actions/checkout@v2 -> actions/checkout@v3 2023-06-29 06:13:10 -07:00
55ddfbef62 Bump actions/checkout in example 2023-06-29 06:13:10 -07:00
dec3bc3c9b fix: removed commented commit escaping code 2023-03-29 11:11:22 -07:00
ad81b423ab fix: use multiline string 2023-03-29 11:11:22 -07:00
c7487e8c98 doc: doc a bit more specific on the options format 2023-03-29 11:11:22 -07:00
54eb0b2901 doc: Info in readme 2023-03-29 11:11:22 -07:00
8a88a06550 fix: pr message fix 2023-03-29 11:11:22 -07:00
9af2d0f36a fix : replace action using deprecated node 12 2023-03-29 11:11:22 -07:00
b55ee105d9 feat: Added nix option
fix: nix options position

Use empty list


fix options
2023-03-29 11:11:22 -07:00
bc75a5b55e expose status of PR 2023-03-27 09:17:55 -07:00
786e5cf5a2 allow to set base branch of pull request 2023-03-27 08:43:21 -07:00
085c3a0b6d build(deps): bump pedrolamas/handlebars-action from 2.1.0 to 2.2.0
Bumps [pedrolamas/handlebars-action](https://github.com/pedrolamas/handlebars-action) from 2.1.0 to 2.2.0.
- [Release notes](https://github.com/pedrolamas/handlebars-action/releases)
- [Commits](https://github.com/pedrolamas/handlebars-action/compare/v2.1.0...v2.2.0)

---
updated-dependencies:
- dependency-name: pedrolamas/handlebars-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 05:55:07 -08:00
29d64d0332 Update Nix install action in README 2023-03-06 05:47:19 -08:00
cc83127440 build(deps): bump peter-evans/create-pull-request from 3 to 4
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 3 to 4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v3...v4)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 05:46:37 -08:00
6411dd26e0 Switch to Nix Installer Action 2023-02-28 09:20:08 -08:00
6f9746fc32 Merge pull request #48 from DeterminateSystems/dependabot/github_actions/nwisbeta/validate-yaml-schema-2.0.0
build(deps): bump nwisbeta/validate-yaml-schema from 1.0.3 to 2.0.0
2023-02-02 17:03:57 +01:00
483538ef54 Merge pull request #55 from DeterminateSystems/dependabot/github_actions/cachix/install-nix-action-18
build(deps): bump cachix/install-nix-action from 17 to 18
2023-01-31 14:55:19 +00:00
114dde340d Merge pull request #57 from DeterminateSystems/dependabot/github_actions/pedrolamas/handlebars-action-2.1.0
build(deps): bump pedrolamas/handlebars-action from 2.0.0 to 2.1.0
2023-01-27 16:00:40 +01:00
876a472251 fix(deps): upgrade DamianReeves/write-file-action to v1.2
https://github.com/DamianReeves/write-file-action/releases/tag/v1.2

This bumps the write-file-action from the Node.js 12 runtime to Node.js
16, avoiding a warning that Node.js 12 actions are deprecated[^1].

[^1]: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/
2023-01-23 07:15:35 -08:00
a0c5484d59 feat: accept list of reviewers and assignees
Pass a list of GitHub usernames through to
peter-evans/create-pull-request.

Assignees are specified with the `pr-assignees` property.
Reviewers are specified with the `pr-reviewers` property.

Both properties expect the value to be a list of GitHub usernames,
separated by either commas or newlines.
2023-01-19 07:29:15 -08:00
766761fdfc build(deps): bump pedrolamas/handlebars-action from 2.0.0 to 2.1.0
Bumps [pedrolamas/handlebars-action](https://github.com/pedrolamas/handlebars-action) from 2.0.0 to 2.1.0.
- [Release notes](https://github.com/pedrolamas/handlebars-action/releases)
- [Commits](https://github.com/pedrolamas/handlebars-action/compare/v2.0.0...v2.1.0)

---
updated-dependencies:
- dependency-name: pedrolamas/handlebars-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-08 01:17:13 +00:00
5f6870f3a9 build(deps): bump cachix/install-nix-action from 17 to 18
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 17 to 18.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Commits](https://github.com/cachix/install-nix-action/compare/v17...v18)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-13 01:34:40 +00:00
1e98f70b34 build(deps): bump nwisbeta/validate-yaml-schema from 1.0.3 to 2.0.0
Bumps [nwisbeta/validate-yaml-schema](https://github.com/nwisbeta/validate-yaml-schema) from 1.0.3 to 2.0.0.
- [Release notes](https://github.com/nwisbeta/validate-yaml-schema/releases)
- [Commits](https://github.com/nwisbeta/validate-yaml-schema/compare/v1.0.3...v2.0.0)

---
updated-dependencies:
- dependency-name: nwisbeta/validate-yaml-schema
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-19 18:42:46 +00:00
27 changed files with 108929 additions and 161 deletions

View File

@ -1,15 +1,10 @@
# EditorConfig helps developers define and maintain consistent # https://editorconfig.org
# coding styles between different editors and IDEs
# editorconfig.org
root = true root = true
[*] [*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space indent_style = space
[*.{yml,yaml}]
indent_size = 2 indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

1
.envrc Normal file
View File

@ -0,0 +1 @@
use flake

74
.eslintrc.json Normal file
View File

@ -0,0 +1,74 @@
{
"plugins": ["@typescript-eslint"],
"extends": ["plugin:github/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module",
"project": "./tsconfig.json"
},
"settings": {
"import/resolver": {
"typescript": {}
}
},
"rules": {
"i18n-text/no-en": "off",
"eslint-comments/no-use": "off",
"import/no-namespace": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_"
}
],
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
"accessibility": "no-public"
}
],
"@typescript-eslint/no-base-to-string": "error",
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/array-type": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/ban-ts-comment": "error",
"camelcase": "error",
"@typescript-eslint/consistent-type-assertions": "error",
"@typescript-eslint/explicit-function-return-type": [
"error",
{
"allowExpressions": true
}
],
"@typescript-eslint/func-call-spacing": ["error", "never"],
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-extraneous-class": "error",
"@typescript-eslint/no-for-in-array": "error",
"@typescript-eslint/no-inferrable-types": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-unnecessary-qualifier": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-useless-constructor": "error",
"@typescript-eslint/no-var-requires": "error",
"@typescript-eslint/prefer-for-of": "warn",
"@typescript-eslint/prefer-function-type": "warn",
"@typescript-eslint/prefer-includes": "error",
"@typescript-eslint/prefer-string-starts-ends-with": "error",
"@typescript-eslint/promise-function-async": "error",
"@typescript-eslint/require-array-sort-compare": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unbound-method": "error"
},
"env": {
"node": true,
"es6": true
}
}

View File

@ -5,13 +5,29 @@ on:
branches: [main] branches: [main]
jobs: jobs:
shellcheck: typescript-action:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v17 uses: DeterminateSystems/nix-installer-action@main
- name: Shellcheck - name: Enable magic Nix cache
run: nix-shell --run 'shellcheck $(find . -type f -name "*.sh" -executable)' uses: DeterminateSystems/magic-nix-cache-action@main
- name: Install pnpm dependencies
run: nix develop --command pnpm install
- name: Check formatting
run: nix develop --command pnpm run check-fmt
- name: Lint
run: nix develop --command pnpm run lint
- name: Build
run: nix develop --command pnpm run build
- name: Run test suite
run: nix develop --command pnpm run test
- name: Package
run: nix develop --command pnpm run package
- name: Check git status
run: git status --porcelain=v1
- name: Ensure no staged changes
run: git diff --exit-code

View File

@ -2,18 +2,21 @@ name: update-flake-lock
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: '0 0 * * 0' - cron: "0 0 * * 0"
jobs: jobs:
lockfile: lockfile:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- name: Checkout repository - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v17 uses: DeterminateSystems/nix-installer-action@main
with: - name: Enable magic Nix cache
extra_nix_config: | uses: DeterminateSystems/magic-nix-cache-action@main
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - name: Check flake
uses: DeterminateSystems/flake-checker-action@main
- name: Update flake.lock - name: Update flake.lock
uses: ./. uses: ./.
with:
_internal-strict-mode: true

View File

@ -6,13 +6,13 @@ on:
jobs: jobs:
validate: validate:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Validate YAML - name: Validate YAML
uses: nwisbeta/validate-yaml-schema@v1.0.3 uses: nwisbeta/validate-yaml-schema@v2.0.0
with: with:
yamlSchemasJson: | yamlSchemasJson: |
{ {

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# JS dependencies
node_modules/

5
.prettierignore Normal file
View File

@ -0,0 +1,5 @@
dist/
lib/
node_modules/
pnpm-lock.yaml
README.md

116
README.md
View File

@ -20,14 +20,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v16 uses: DeterminateSystems/nix-installer-action@main
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock - name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX uses: DeterminateSystems/update-flake-lock@main
with: with:
pr-title: "Update flake.lock" # Title of PR to be created pr-title: "Update flake.lock" # Title of PR to be created
pr-labels: | # Labels to be set on the PR pr-labels: | # Labels to be set on the PR
@ -53,18 +50,40 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v16 uses: DeterminateSystems/nix-installer-action@v1
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock - name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX uses: DeterminateSystems/update-flake-lock@vX
with: with:
inputs: input1 input2 input3 inputs: input1 input2 input3
``` ```
## Example adding options to nix command
It is also possible to use specific options to the nix command in a space separated list:
```yaml
name: update-flake-lock
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
jobs:
lockfile:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v1
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX
with:
nix-options: --debug --log-format raw
```
## Example that prints the number of the created PR ## Example that prints the number of the created PR
```yaml ```yaml
@ -79,12 +98,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v16 uses: DeterminateSystems/nix-installer-action@v1
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock - name: Update flake.lock
id: update id: update
uses: DeterminateSystems/update-flake-lock@vX uses: DeterminateSystems/update-flake-lock@vX
@ -111,12 +127,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v16 uses: DeterminateSystems/nix-installer-action@v1
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock - name: Update flake.lock
if: ${{ github.event_name != 'pull_request' }} if: ${{ github.event_name != 'pull_request' }}
uses: DeterminateSystems/update-flake-lock@vX uses: DeterminateSystems/update-flake-lock@vX
@ -125,6 +138,23 @@ jobs:
path-to-flake-dir: 'nix/' # in this example our flake doesn't sit at the root of the repository, it sits under 'nix/flake.nix' path-to-flake-dir: 'nix/' # in this example our flake doesn't sit at the root of the repository, it sits under 'nix/flake.nix'
``` ```
You can also run the update operation in multiple directories, provided that each directory is a valid flake:
```yaml
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX
with:
flake-dirs: |
flake1
flake2
flake3
```
> **Warning**: If you choose multiple directories, `update-flake-lock` can only update all flake inputs,
> meaning that you can't set the `inputs` parameter. This is due to limitations in input handling in
> GitHub Actions, which only allows for strings, numbers, Booleans, and arrays but not objects, which
> would be the much preferred data type for expressing per-directory inputs.
## Example using a different Git user ## Example using a different Git user
If you want to change the author and / or committer of the flake.lock update commit, you can tweak the `git-{author,committer}-{name,email}` options: If you want to change the author and / or committer of the flake.lock update commit, you can tweak the `git-{author,committer}-{name,email}` options:
@ -141,12 +171,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v16 uses: DeterminateSystems/nix-installer-action@v1
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock - name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX uses: DeterminateSystems/update-flake-lock@vX
with: with:
@ -189,9 +216,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v16 uses: DeterminateSystems/nix-installer-action@v1
- name: Update flake.lock - name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX uses: DeterminateSystems/update-flake-lock@vX
with: with:
@ -206,7 +233,7 @@ You can follow [Github's guide on creating and/or adding a new GPG key to an use
For the bot to produce signed commits, you will have to provide the GPG private keys to this action's input parameters. You can safely do that with [Github secrets as explained here](https://github.com/crazy-max/ghaction-import-gpg#prerequisites). For the bot to produce signed commits, you will have to provide the GPG private keys to this action's input parameters. You can safely do that with [Github secrets as explained here](https://github.com/crazy-max/ghaction-import-gpg#prerequisites).
When using commit signing, the commit author name and email for the commits produced by this bot would correspond to the ones associated to the GPG Public Key. When using commit signing, the commit author name and email for the commits produced by this bot would correspond to the ones associated to the GPG Public Key.
If you want to sign using a subkey, you must specify the subkey fingerprint using the `gpg-fingerprint` input parameter. If you want to sign using a subkey, you must specify the subkey fingerprint using the `gpg-fingerprint` input parameter.
@ -224,9 +251,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
uses: cachix/install-nix-action@v16 uses: DeterminateSystems/nix-installer-action@v1
- name: Update flake.lock - name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX uses: DeterminateSystems/update-flake-lock@vX
with: with:
@ -269,6 +296,33 @@ However you can customize it, with variable interpolation performed with [Handle
- env.GIT_COMMITTER_EMAIL - env.GIT_COMMITTER_EMAIL
- env.GIT_COMMIT_MESSAGE - env.GIT_COMMIT_MESSAGE
## Add assignees or reviewers
You can assign the PR to or request a review from one or more GitHub users with `pr-assignees` and `pr-reviewers`, respectively.
These properties expect a comma or newline separated list of GitHub usernames:
```yaml
name: update-flake-lock
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: '0 0 * * 1,4' # Run twice a week
jobs:
lockfile:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v1
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@vX
with:
pr-assignees: SomeGitHubUsername
pr-reviewers: SomeOtherGitHubUsername,SomeThirdGitHubUsername
```
## Contributing ## Contributing
Feel free to send a PR or open an issue if you find something functions unexpectedly! Please make sure to test your changes and update any related documentation before submitting your PR. Feel free to send a PR or open an issue if you find something functions unexpectedly! Please make sure to test your changes and update any related documentation before submitting your PR.

View File

@ -1,32 +1,65 @@
name: 'Update flake.lock' name: "Update Nix Flake Lock"
description: 'Update your flake.lock and send a PR' description: "Update your Nix flake.lock and send a PR"
inputs: inputs:
inputs: inputs:
description: 'A space-separated list of inputs to update. Leave empty to update all inputs.' description: "A space-separated list of inputs to update. Leave empty to update all inputs."
required: false required: false
default: '' default: ""
token: token:
description: 'GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT)' description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT)"
required: false required: false
default: ${{ github.token }} default: ${{ github.token }}
commit-msg: commit-msg-template:
description: 'The message provided with the commit' description: |
The commit message template to use. You can use these variables in your template:
* `{{ flake_dot_lock }}` is the path to the `flake.lock` file being updated
* `{{ flake_dot_lock_dir }}` is the `flake.lock` file's directory
If you set both this and `commit-msg`, the `commit-msg` setting is used (it does not support templating).
required: false
default: |
flake.lock: Updated in {{ flake_dot_lock_dir }}
commit-msg:
description: |
The message provided with the commit.
required: false
base:
description: "Sets the pull request base branch. Defaults to the branch checked out in the workflow."
required: false required: false
default: "flake.lock: Update"
branch: branch:
description: 'The branch of the PR to be created' description: "The branch of the PR to be created"
required: false required: false
default: "update_flake_lock_action" default: "update_flake_lock_action"
path-to-flake-dir: path-to-flake-dir:
description: 'The path of the directory containing `flake.nix` file within your repository. Useful when `flake.nix` cannot reside at the root of your repository.' description: |
The path of the directory containing `flake.nix` file within your repository.
Useful when `flake.nix` cannot reside at the root of your repository.
required: false required: false
default: '' flake-dirs:
description: |
A space-separated list of directories containing `flake.nix` files within your repository.
Useful when you have multiple flakes in your repository.
required: false
default: ""
pr-title: pr-title:
description: 'The title of the PR to be created' description: "The title of the PR to be created"
required: false required: false
default: "flake.lock: Update" default: "flake.lock: Update"
pr-body-template:
description: |
The pull request body template to use. You can use these variables in your template:
* `{{ comma_separated_dirs }}` is the flake directories that were updated separated by comma
* `{{ space_separated_dirs }}` is the flake directories that were updated separated by space
* `{{ updated_dirs_list }}` is the flake directories that were updated as a Markdown list
If you set both this and `pr-body`, the `pr-body` setting is used (it does not support templating).
required: false
default: |
Just testing.
pr-body: pr-body:
description: 'The body of the PR to be created' description: "The body of the PR to be created"
required: false required: false
default: | default: |
Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action. Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.
@ -50,54 +83,73 @@ inputs:
``` ```
pr-labels: pr-labels:
description: 'A comma or newline separated list of labels to set on the Pull Request to be created' description: "A comma or newline separated list of labels to set on the Pull Request to be created"
required: false required: false
default: '' default: ""
pr-assignees:
description: "A comma or newline separated list of assignees (GitHub usernames)."
required: false
default: ""
pr-reviewers:
description: "A comma or newline separated list of reviewers (GitHub usernames) to request a review from."
required: false
default: ""
git-author-name: git-author-name:
description: 'Author name used for commit. Only used if sign-commits is false.' description: "Author name used for commit. Only used if sign-commits is false."
required: false required: false
default: 'github-actions[bot]' default: "github-actions[bot]"
git-author-email: git-author-email:
description: 'Author email used for commit. Only used if sign-commits is false.' description: "Author email used for commit. Only used if sign-commits is false."
required: false required: false
default: 'github-actions[bot]@users.noreply.github.com' default: "github-actions[bot]@users.noreply.github.com"
git-committer-name: git-committer-name:
description: 'Committer name used for commit. Only used if sign-commits is false.' description: "Committer name used for commit. Only used if sign-commits is false."
required: false required: false
default: 'github-actions[bot]' default: "github-actions[bot]"
git-committer-email: git-committer-email:
description: 'Committer email used for commit. Only used if sign-commits is false.' description: "Committer email used for commit. Only used if sign-commits is false."
required: false required: false
default: 'github-actions[bot]@users.noreply.github.com' default: "github-actions[bot]@users.noreply.github.com"
sign-commits: sign-commits:
description: 'Set to true if the action should sign the commit with GPG' description: "Set to true if the action should sign the commit with GPG"
required: false required: false
default: 'false' default: "false"
gpg-private-key: gpg-private-key:
description: 'GPG Private Key with which to sign the commits in the PR to be created' description: "GPG Private Key with which to sign the commits in the PR to be created"
required: false required: false
default: '' default: ""
gpg-fingerprint: gpg-fingerprint:
description: 'Fingerprint of specific GPG subkey to use' description: "Fingerprint of specific GPG subkey to use"
required: false required: false
gpg-passphrase: gpg-passphrase:
description: 'GPG Private Key Passphrase for the GPG Private Key with which to sign the commits in the PR to be created' description: "GPG Private Key Passphrase for the GPG Private Key with which to sign the commits in the PR to be created"
required: false required: false
default: '' default: ""
nix-options:
description: "A space-separated list of options to pass to the nix command"
required: false
default: ""
_internal-strict-mode:
description: Whether to fail when any errors are thrown. Used only to test the Action; do not set this in your own workflows.
required: false
default: false
outputs: outputs:
pull-request-number: pull-request-number:
description: 'The number of the opened pull request' description: "The number of the opened pull request"
value: ${{ steps.create-pr.outputs.pull-request-number }} value: ${{ steps.create-pr.outputs.pull-request-number }}
pull-request-operation:
description: "The pull request operation performed by the action, `created`, `updated` or `closed`."
value: ${{ steps.create-pr.outputs.pull-request-operation }}
runs: runs:
using: "composite" using: "composite"
steps: steps:
- name: Import bot's GPG key for signing commits - name: Import bot's GPG key for signing commits
if: ${{ inputs.sign-commits == 'true' }} if: ${{ inputs.sign-commits == 'true' }}
id: import-gpg id: import-gpg
uses: crazy-max/ghaction-import-gpg@v5 uses: crazy-max/ghaction-import-gpg@v6
with: with:
gpg_private_key: ${{ inputs.gpg-private-key }} gpg_private_key: ${{ inputs.gpg-private-key }}
fingerprint: ${{ inputs.gpg-fingerprint }} fingerprint: ${{ inputs.gpg-fingerprint }}
passphrase: ${{ inputs.gpg-passphrase }} passphrase: ${{ inputs.gpg-passphrase }}
git_config_global: true git_config_global: true
git_user_signingkey: true git_user_signingkey: true
@ -124,40 +176,62 @@ runs:
echo "GIT_AUTHOR_EMAIL=<${{ inputs.git-author-email }}>" >> $GITHUB_ENV echo "GIT_AUTHOR_EMAIL=<${{ inputs.git-author-email }}>" >> $GITHUB_ENV
echo "GIT_COMMITTER_NAME=${{ inputs.git-committer-name }}" >> $GITHUB_ENV echo "GIT_COMMITTER_NAME=${{ inputs.git-committer-name }}" >> $GITHUB_ENV
echo "GIT_COMMITTER_EMAIL=<${{ inputs.git-committer-email }}>" >> $GITHUB_ENV echo "GIT_COMMITTER_EMAIL=<${{ inputs.git-committer-email }}>" >> $GITHUB_ENV
- name: Run update-flake-lock.sh - name: Run update-flake-lock
run: $GITHUB_ACTION_PATH/update-flake-lock.sh id: update-flake-lock
shell: bash shell: bash
run: node "$GITHUB_ACTION_PATH/dist/index.js"
env: env:
GIT_AUTHOR_NAME: ${{ env.GIT_AUTHOR_NAME }} # The following manually exposes all of the action inputs into INPUT_ environment variables so actionsCore.getInput works:
GIT_AUTHOR_EMAIL: ${{ env.GIT_AUTHOR_EMAIL }} # https://github.com/actions/toolkit/blob/ae38557bb0dba824cdda26ce787bd6b66cf07a83/packages/core/src/core.ts#L126
GIT_COMMITTER_NAME: ${{ env.GIT_COMMITTER_NAME }} INPUT_BASE: ${{ inputs.base }}
GIT_COMMITTER_EMAIL: ${{ env.GIT_COMMITTER_EMAIL }} INPUT_BRANCH: ${{ inputs.branch }}
TARGETS: ${{ inputs.inputs }} INPUT_COMMIT-MSG: ${{ inputs.commit-msg }}
COMMIT_MSG: ${{ inputs.commit-msg }} INPUT_COMMIT-MSG-TEMPLATE: ${{ inputs.commit-msg-template }}
PATH_TO_FLAKE_DIR: ${{ inputs.path-to-flake-dir }} INPUT_GIT-AUTHOR-EMAIL: ${{ inputs.git-author-email }}
INPUT_GIT-AUTHOR-NAME: ${{ inputs.git-author-name }}
INPUT_GIT-COMMITTER-EMAIL: ${{ inputs.git-committer-email }}
INPUT_GIT-COMMITTER-NAME: ${{ inputs.git-committer-name }}
INPUT_GPG-FINGERPRINT: ${{ inputs.gpg-fingerprint }}
INPUT_GPG-PASSPHRASE: ${{ inputs.gpg-passphrase }}
INPUT_GPG-PRIVATE-KEY: ${{ inputs.gpg-private-key }}
INPUT_INPUTS: ${{ inputs.inputs }}
INPUT_NIX-OPTIONS: ${{ inputs.nix-options }}
INPUT_PATH-TO-FLAKE-DIR: ${{ inputs.path-to-flake-dir }}
INPUT_FLAKE-DIRS: ${{ inputs.flake-dirs }}
INPUT_PR-ASSIGNEES: ${{ inputs.pr-assignees }}
INPUT_PR-BODY: ${{ inputs.pr-body }}
INPUT_PR-BODY-TEMPLATE: ${{ inputs.pr-body-template }}
INPUT_PR-LABELS: ${{ inputs.pr-labels }}
INPUT_PR-REVIEWERS: ${{ inputs.pr-reviewers }}
INPUT_PR-TITLE: ${{ inputs.pr-title }}
INPUT_PULL-REQUEST-NUMBER: ${{ inputs.pull-request-number }}
INPUT_PULL-REQUEST-OPERATION: ${{ inputs.pull-request-operation }}
INPUT_SIGN-COMMITS: ${{ inputs.sign-commits }}
INPUT_TOKEN: ${{ inputs.token }}
INPUT__INTERNAL-STRICT-MODE: ${{ inputs._internal-strict-mode }}
- name: Save PR Body as file - name: Save PR Body as file
uses: DamianReeves/write-file-action@v1.1 uses: DamianReeves/write-file-action@v1.3
with: with:
path: pr_body.template path: pr_body.template
contents: ${{ inputs.pr-body }} contents: ${{ steps.update-flake-lock.outputs.pr-body }}
env: {} env: {}
- name: Set additional env variables (GIT_COMMIT_MESSAGE) - name: Set additional env variables (GIT_COMMIT_MESSAGE)
shell: bash shell: bash
run: | run: |
GIT_COMMIT_MESSAGE="$(git log --format=%b -n 1)" DELIMITER=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
GIT_COMMIT_MESSAGE="${GIT_COMMIT_MESSAGE//'%'/'%25'}" COMMIT_MESSAGE="$(git log --format=%b -n 1)"
GIT_COMMIT_MESSAGE="${GIT_COMMIT_MESSAGE//$'\n'/'%0A'}" echo "GIT_COMMIT_MESSAGE<<$DELIMITER" >> $GITHUB_ENV
GIT_COMMIT_MESSAGE="${GIT_COMMIT_MESSAGE//$'\r'/'%0D'}" echo "$COMMIT_MESSAGE" >> $GITHUB_ENV
echo "GIT_COMMIT_MESSAGE=$GIT_COMMIT_MESSAGE" >> $GITHUB_ENV echo "$DELIMITER" >> $GITHUB_ENV
echo "GIT_COMMIT_MESSAGE is: ${GIT_COMMIT_MESSAGE}" echo "GIT_COMMIT_MESSAGE is: ${COMMIT_MESSAGE}"
- name: Interpolate PR Body - name: Interpolate PR Body
uses: pedrolamas/handlebars-action@v2.0.0 uses: pedrolamas/handlebars-action@v2.4.0
with: with:
files: 'pr_body.template' files: "pr_body.template"
output-filename: 'pr_body.txt' output-filename: "pr_body.txt"
- name: Read pr_body.txt - name: Read pr_body.txt
id: pr_body id: pr_body
uses: andstor/file-reader-action@v1 uses: juliangruber/read-file-action@v1
with: with:
path: "pr_body.txt" path: "pr_body.txt"
# We need to remove the pr_body files so that the # We need to remove the pr_body files so that the
@ -168,13 +242,16 @@ runs:
run: rm -f pr_body.txt pr_body.template run: rm -f pr_body.txt pr_body.template
- name: Create PR - name: Create PR
id: create-pr id: create-pr
uses: peter-evans/create-pull-request@v3 uses: peter-evans/create-pull-request@v6
with: with:
base: ${{ inputs.base }}
branch: ${{ inputs.branch }} branch: ${{ inputs.branch }}
delete-branch: true delete-branch: true
committer: ${{ env.GIT_COMMITTER_NAME }} ${{ env.GIT_COMMITTER_EMAIL }} committer: ${{ env.GIT_COMMITTER_NAME }} ${{ env.GIT_COMMITTER_EMAIL }}
author: ${{ env.GIT_AUTHOR_NAME }} ${{ env.GIT_AUTHOR_EMAIL }} author: ${{ env.GIT_AUTHOR_NAME }} ${{ env.GIT_AUTHOR_EMAIL }}
title: ${{ inputs.pr-title }} title: ${{ inputs.pr-title }}
token: ${{ inputs.token }} token: ${{ inputs.token }}
assignees: ${{ inputs.pr-assignees }}
labels: ${{ inputs.pr-labels }} labels: ${{ inputs.pr-labels }}
body: ${{ steps.pr_body.outputs.contents }} reviewers: ${{ inputs.pr-reviewers }}
body: ${{ steps.pr_body.outputs.content }}

2
dist/index.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export { }

103570
dist/index.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/index.js.map vendored Normal file

File diff suppressed because one or more lines are too long

3
dist/package.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"type": "module"
}

18
flake.lock generated
View File

@ -2,18 +2,16 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1659131907, "lastModified": 1713537308,
"narHash": "sha256-8bz4k18M/FuVC+EVcI4aREN2PsEKT7LGmU2orfjnpCg=", "narHash": "sha256-XtTSSIB2DA6tOv+l0FhvfDMiyCmhoRbNB+0SeInZkbk=",
"owner": "nixos", "rev": "5c24cf2f0a12ad855f444c30b2421d044120c66f",
"repo": "nixpkgs", "revCount": 614481,
"rev": "8d435fca5c561da8168abb30270788d2da2a7951", "type": "tarball",
"type": "github" "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.614481%2Brev-5c24cf2f0a12ad855f444c30b2421d044120c66f/018efa00-a443-7f41-b371-ce568b5c7e9f/source.tar.gz"
}, },
"original": { "original": {
"owner": "nixos", "type": "tarball",
"ref": "nixos-unstable", "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz"
"repo": "nixpkgs",
"type": "github"
} }
}, },
"root": { "root": {

View File

@ -1,30 +1,23 @@
{ {
description = "update-flake-lock"; description = "update-flake-lock";
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz";
outputs = outputs = { self, nixpkgs }:
{ self
, nixpkgs
}:
let let
nameValuePair = name: value: { inherit name value; }; supportedSystems = [ "x86_64-linux" "aarch64-darwin" "aarch64-linux" "x86_64-darwin" ];
genAttrs = names: f: builtins.listToAttrs (map (n: nameValuePair n (f n)) names); forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit system; };
allSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; });
forAllSystems = f: genAttrs allSystems
(system: f {
inherit system;
pkgs = import nixpkgs { inherit system; };
});
in in
{ {
devShell = forAllSystems devShells = forEachSupportedSystem ({ pkgs }: {
({ system, pkgs, ... }: default = pkgs.mkShell {
pkgs.stdenv.mkDerivation { packages = with pkgs; [
name = "update-flake-lock-devshell"; nodejs_latest
buildInputs = [ pkgs.shellcheck ]; nodePackages_latest.pnpm
src = self; ];
}); };
});
}; };
} }

49
package.json Normal file
View File

@ -0,0 +1,49 @@
{
"name": "update-flake-lock",
"version": "1.0.0",
"description": "",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"scripts": {
"build": "tsup",
"format": "prettier --write .",
"check-fmt": "prettier --check .",
"lint": "eslint src/**/*.ts --ignore-pattern *.test.ts",
"package": "ncc build",
"test": "vitest --watch false",
"test-dev": "vitest",
"all": "pnpm run format && pnpm run lint && pnpm run build && pnpm run package"
},
"repository": {
"type": "git",
"url": "git+https://github.com/DeterminateSystems/update-flake-lock.git"
},
"keywords": [],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/DeterminateSystems/update-flake-lock/issues"
},
"homepage": "https://github.com/DeterminateSystems/update-flake-lock#readme",
"dependencies": {
"@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1",
"detsys-ts": "github:DeterminateSystems/detsys-ts",
"handlebars": "^4.7.8"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-github": "^4.10.2",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"prettier": "^3.2.5",
"tsup": "^8.0.2",
"typescript": "^5.4.5",
"vitest": "^1.6.0"
}
}

4508
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

12
prettier.config.cjs Normal file
View File

@ -0,0 +1,12 @@
/** @type {import('prettier').Config} */
module.exports = {
plugins: [require.resolve("@trivago/prettier-plugin-sort-imports")],
semi: true,
singleQuote: false,
tabWidth: 2,
trailingComma: "all",
useTabs: false,
// Import sorting
importOrderSeparation: true,
importOrderSortSpecifiers: true,
};

184
src/index.ts Normal file
View File

@ -0,0 +1,184 @@
import { makeNixCommandArgs } from "./nix.js";
import { renderCommitMessage, renderPullRequestBody } from "./template.js";
import * as actionsCore from "@actions/core";
import * as actionsExec from "@actions/exec";
import { DetSysAction, inputs } from "detsys-ts";
import * as fs from "fs";
const DEFAULT_FLAKE_DIR = ".";
const PR_BODY_OUTPUT_KEY = "pr-body";
const EVENT_EXECUTION_FAILURE = "execution_failure";
class UpdateFlakeLockAction extends DetSysAction {
private commitMessage: string;
private commitMessageTemplate: string;
private prBody: string;
private prBodyTemplate: string;
private nixOptions: string[];
private flakeInputs: string[];
private pathToFlakeDir: string | null;
private flakeDirsInput: string[] | null;
private flakeDirs: string[];
constructor() {
super({
name: "update-flake-lock",
fetchStyle: "universal",
requireNix: "fail",
});
this.commitMessage = inputs.getString("commit-msg");
this.commitMessageTemplate = inputs.getString("commit-msg-template");
this.prBody = inputs.getString("pr-body");
this.prBodyTemplate = inputs.getString("pr-body-template");
this.flakeInputs = inputs.getArrayOfStrings("inputs", "space");
this.nixOptions = inputs.getArrayOfStrings("nix-options", "space");
this.pathToFlakeDir = inputs.getStringOrNull("path-to-flake-dir");
this.flakeDirsInput = inputs.getArrayOfStringsOrNull("flake-dirs", "space");
this.validateInputs();
if (this.flakeDirsInput !== null && this.flakeDirsInput.length > 0) {
this.flakeDirs = this.flakeDirsInput;
} else {
this.flakeDirs = [this.pathToFlakeDir ?? DEFAULT_FLAKE_DIR];
}
}
async main(): Promise<void> {
for (const directory of this.flakeDirs) {
await this.updateFlakeInDirectory(directory);
}
const prBody =
this.prBody !== ""
? this.prBody
: renderPullRequestBody(this.prBodyTemplate, this.flakeDirs);
actionsCore.setOutput(PR_BODY_OUTPUT_KEY, prBody);
}
// No post phase
async post(): Promise<void> {}
private async updateFlakeInDirectory(flakeDir: string): Promise<void> {
this.ensureDirectoryExists(flakeDir);
this.ensureDirectoryIsFlake(flakeDir);
actionsCore.debug(`Running flake lock update in directory \`${flakeDir}\``);
const flakeDotLock = `${flakeDir}/flake.lock`;
const commitMessage =
this.commitMessage !== ""
? this.commitMessage
: renderCommitMessage(
this.commitMessageTemplate,
flakeDir,
flakeDotLock,
);
// Nix command of this form:
// nix ${maybe nix options} flake ${"update" or "lock"} ${maybe --update-input flags} --commit-lock-file --commit-lockfile-summary ${commit message}
// Example commands:
// nix --extra-substituters https://example.com flake lock --update-input nixpkgs --commit-lock-file --commit-lockfile-summary "updated flake.lock"
// nix flake update --commit-lock-file --commit-lockfile-summary "updated flake.lock"
const nixCommandArgs: string[] = makeNixCommandArgs(
this.nixOptions,
this.flakeInputs,
commitMessage,
);
actionsCore.debug(
JSON.stringify({
directory: flakeDir,
options: this.nixOptions,
inputs: this.flakeInputs,
message: this.commitMessage,
args: nixCommandArgs,
}),
);
const execOptions: actionsExec.ExecOptions = {
cwd: flakeDir,
};
const exitCode = await actionsExec.exec("nix", nixCommandArgs, execOptions);
if (exitCode !== 0) {
this.recordEvent(EVENT_EXECUTION_FAILURE, {
exitCode,
});
actionsCore.setFailed(
`non-zero exit code of ${exitCode} detected while updating directory \`${flakeDir}\``,
);
} else {
actionsCore.info(
`flake.lock file in \`${flakeDir}\` was successfully updated`,
);
}
}
private validateInputs(): void {
// Ensure that either `path-to-flake-dir` or `flake-dirs` is set to a meaningful value but not both
if (
this.flakeDirsInput !== null &&
this.flakeDirsInput.length > 0 &&
this.pathToFlakeDir !== null &&
this.pathToFlakeDir !== ""
) {
throw new Error(
"Both `path-to-flake-dir` and `flake-dirs` are set, whereas only one can be",
);
}
// Ensure that `flake-dirs` isn't an empty array if set
if (this.flakeDirsInput !== null && this.flakeDirsInput.length === 0) {
throw new Error(
"The `flake-dirs` input is set to an empty array; it must contain at least one directory",
);
}
// Ensure that both `flake-dirs` and `inputs` aren't set at the same time
if (
this.flakeDirsInput !== null &&
this.flakeDirsInput.length > 0 &&
this.flakeInputs.length > 0
) {
throw new Error(
`You've set both \`flake-dirs\` and \`inputs\` but you can only set one`,
);
}
}
private ensureDirectoryExists(flakeDir: string): void {
actionsCore.debug(`Checking that flake directory \`${flakeDir}\` exists`);
// Ensure the directory exists
fs.access(flakeDir, fs.constants.F_OK, (err) => {
if (err !== null) {
throw new Error(`Directory \`${flakeDir}\` doesn't exist`);
} else {
actionsCore.debug(`Flake directory \`${flakeDir}\` exists`);
}
});
}
private ensureDirectoryIsFlake(flakeDir: string): void {
const flakeDotNix = `${flakeDir}/flake.nix`;
if (!fs.existsSync(flakeDotNix)) {
throw new Error(
`Directory \`${flakeDir}\` is not a valid flake as it doesn't contain a \`flake.nix\``,
);
} else {
actionsCore.debug(`Directory \`${flakeDir}\` is a valid flake`);
}
}
}
function main(): void {
new UpdateFlakeLockAction().execute();
}
main();

18
src/nix.ts Normal file
View File

@ -0,0 +1,18 @@
// Build the Nix args out of inputs from the Actions environment
export function makeNixCommandArgs(
nixOptions: string[],
flakeInputs: string[],
commitMessage: string,
): string[] {
const flakeInputFlags = flakeInputs.flatMap((input) => [
"--update-input",
input,
]);
const updateLockMechanism = flakeInputFlags.length === 0 ? "update" : "lock";
return nixOptions
.concat(["flake", updateLockMechanism])
.concat(flakeInputFlags)
.concat(["--commit-lock-file", "--commit-lockfile-summary", commitMessage]);
}

75
src/template.test.ts Normal file
View File

@ -0,0 +1,75 @@
import { renderCommitMessage, renderPullRequestBody } from "./template.js";
import { template } from "handlebars";
import { Test, describe, expect, test } from "vitest";
describe("templating", () => {
test("commit message", () => {
type TestCase = {
template: string;
flakeDotLockDir: string;
flakeDotLock: string;
expected: string;
};
const testCases: TestCase[] = [
{
template: "Updating flake.lock in dir {{ flake_dot_lock_dir }}",
flakeDotLockDir: ".",
flakeDotLock: "./flake.lock",
expected: "Updating flake.lock in dir .",
},
{
template:
"Here I go doing some updating of my pristine flake.lock at {{ flake_dot_lock }}",
flakeDotLockDir: "subflake",
flakeDotLock: "subflake/flake.lock",
expected:
"Here I go doing some updating of my pristine flake.lock at subflake/flake.lock",
},
{
template: "This variable doesn't exist: {{ foo }}",
flakeDotLockDir: ".",
flakeDotLock: "./flake.lock",
expected: "This variable doesn't exist: ",
},
];
testCases.forEach(
({ template, flakeDotLockDir, flakeDotLock, expected }) => {
expect(
renderCommitMessage(template, flakeDotLockDir, flakeDotLock),
).toEqual(expected);
},
);
});
test("pull request body", () => {
type TestCase = {
template: string;
dirs: string[];
expected: string;
};
const testCases: TestCase[] = [
{
template: "Updated inputs: {{ comma_separated_dirs }}",
dirs: ["."],
expected: "Updated inputs: .",
},
{
template: "Updated inputs: {{ space_separated_dirs }}",
dirs: ["subflake", "subflake2"],
expected: "Updated inputs: subflake subflake2",
},
{
template: "Updated inputs:\n{{ updated_dirs_list }}",
dirs: ["flake1", "flake2"],
expected: `Updated inputs:\n* flake1\n* flake2`,
},
];
testCases.forEach(({ template, dirs, expected }) => {
expect(renderPullRequestBody(template, dirs)).toEqual(expected);
});
});
});

39
src/template.ts Normal file
View File

@ -0,0 +1,39 @@
import Handlebars from "handlebars";
export function renderPullRequestBody(
template: string,
dirs: string[],
): string {
const commaSeparated = dirs.join(", ");
const spaceSeparated = dirs.join(" ");
const dirsList = dirs.map((d: string) => `* ${d}`).join("\n");
const tpl = Handlebars.compile(template);
return tpl({
// eslint-disable-next-line camelcase
comma_separated_dirs: commaSeparated,
// eslint-disable-next-line camelcase
space_separated_dirs: spaceSeparated,
// eslint-disable-next-line camelcase
updated_dirs_list: dirsList,
});
}
export function renderCommitMessage(
template: string,
flakeDotLockDir: string,
flakeDotLock: string,
): string {
return render(template, {
// eslint-disable-next-line camelcase
flake_dot_lock_dir: flakeDotLockDir,
// eslint-disable-next-line camelcase
flake_dot_lock: flakeDotLock,
});
}
function render(template: string, inputs: Record<string, string>): string {
const tpl = Handlebars.compile(template);
return tpl(inputs);
}

View File

@ -0,0 +1,74 @@
import { makeNixCommandArgs } from "./nix.js";
import { expect, test } from "vitest";
test("Nix command arguments", () => {
type TestCase = {
inputs: {
nixOptions: string[];
flakeInputs: string[];
commitMessage: string;
};
expected: string[];
};
const testCases: TestCase[] = [
{
inputs: {
nixOptions: ["--log-format", "raw"],
flakeInputs: [],
commitMessage: "just testing",
},
expected: [
"--log-format",
"raw",
"flake",
"update",
"--commit-lock-file",
"--commit-lockfile-summary",
"just testing",
],
},
{
inputs: {
nixOptions: [],
flakeInputs: ["nixpkgs", "rust-overlay"],
commitMessage: "just testing",
},
expected: [
"flake",
"lock",
"--update-input",
"nixpkgs",
"--update-input",
"rust-overlay",
"--commit-lock-file",
"--commit-lockfile-summary",
"just testing",
],
},
{
inputs: {
nixOptions: ["--debug"],
flakeInputs: [],
commitMessage: "just testing",
},
expected: [
"--debug",
"flake",
"update",
"--commit-lock-file",
"--commit-lockfile-summary",
"just testing",
],
},
];
testCases.forEach(({ inputs, expected }) => {
const args = makeNixCommandArgs(
inputs.nixOptions,
inputs.flakeInputs,
inputs.commitMessage,
);
expect(args).toStrictEqual(expected);
});
});

15
tsconfig.json Normal file
View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
"module": "Node16",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"resolveJsonModule": true,
"declaration": true
},
"exclude": ["node_modules", "**/*.test.ts", "dist"]
}

16
tsup.config.ts Normal file
View File

@ -0,0 +1,16 @@
import { name } from "./package.json";
import { defineConfig } from "tsup";
export default defineConfig({
name,
entry: ["src/index.ts"],
format: ["esm"],
target: "node20",
bundle: true,
splitting: false,
sourcemap: true,
clean: true,
dts: {
resolve: true,
},
});

View File

@ -1,16 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ -n "$PATH_TO_FLAKE_DIR" ]]; then
cd "$PATH_TO_FLAKE_DIR"
fi
if [[ -n "$TARGETS" ]]; then
inputs=()
for input in $TARGETS; do
inputs+=("--update-input" "$input")
done
nix flake lock "${inputs[@]}" --commit-lock-file --commit-lockfile-summary "$COMMIT_MSG"
else
nix flake update --commit-lock-file --commit-lockfile-summary "$COMMIT_MSG"
fi