Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ jobs:
token: ${{ secrets.GH_TOKEN_FOR_UPDATES }}
```

## Sign-off commit

The bot can produce commits with a sign-off. This is useful for projects that require a sign-off to be present in the commit message.
To enable this, set the `signoff` input to `true`.


## With GPG commit signing

It's possible for the bot to produce GPG-signed commits.
Expand Down
21 changes: 10 additions & 11 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ inputs:
Automated changes by the [update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock) GitHub Action.

```
{{ env.GIT_COMMIT_MESSAGE }}
{{ env.FLAKE_UPDATE_OUTPUT }}
```

### Running GitHub Actions on this PR

GitHub Actions will not run workflows on pull requests which are opened by a GitHub Action.

**To run GitHub Actions workflows on this PR, close and re-open this pull request.**

pr-labels:
description: "A comma or newline separated list of labels to set on the Pull Request to be created"
required: false
Expand Down Expand Up @@ -75,6 +74,10 @@ inputs:
description: "Set to true if the action should sign the commit with GPG"
required: false
default: "false"
signoff:
description: "Set to true if the action should add a Signed-off-by line to the commit message"
required: false
default: "false"
gpg-private-key:
description: "GPG Private Key with which to sign the commits in the PR to be created"
required: false
Expand Down Expand Up @@ -175,15 +178,6 @@ runs:
path: pr_body.template
contents: ${{ inputs.pr-body }}
env: {}
- name: Set additional env variables (GIT_COMMIT_MESSAGE)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed anymore: the variable is set directly inside the index.ts as FLAKE_UPDATE_OUTPUT

shell: bash
run: |
DELIMITER=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
COMMIT_MESSAGE="$(git log --format=%b -n 1)"
echo "GIT_COMMIT_MESSAGE<<$DELIMITER" >> $GITHUB_ENV
echo "$COMMIT_MESSAGE" >> $GITHUB_ENV
echo "$DELIMITER" >> $GITHUB_ENV
echo "GIT_COMMIT_MESSAGE is: ${COMMIT_MESSAGE}"
- name: Interpolate PR Body
uses: pedrolamas/handlebars-action@2995d7eadacbc8f2f6ab8431a01d84a5fa3b8bb4 # v2.4.0
with:
Expand All @@ -207,6 +201,10 @@ runs:
base: ${{ inputs.base }}
branch: ${{ inputs.branch }}
delete-branch: true
commit-message: |
${{ inputs.commit-msg }}

${{ env.FLAKE_UPDATE_OUTPUT }}
committer: ${{ env.GIT_COMMITTER_NAME }} ${{ env.GIT_COMMITTER_EMAIL }}
author: ${{ env.GIT_AUTHOR_NAME }} ${{ env.GIT_AUTHOR_EMAIL }}
title: ${{ inputs.pr-title }}
Expand All @@ -215,3 +213,4 @@ runs:
labels: ${{ inputs.pr-labels }}
reviewers: ${{ inputs.pr-reviewers }}
body: ${{ steps.pr_body.outputs.content }}
signoff: ${{ inputs.signoff }}
36 changes: 24 additions & 12 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -95249,35 +95249,33 @@ function makeOptionsConfident(actionOptions) {
* Copyright (c) 2018-2020 [Samuel Carreira]
*/
//# sourceMappingURL=index.js.map
// EXTERNAL MODULE: external "stream"
var external_stream_ = __nccwpck_require__(2203);
;// CONCATENATED MODULE: ./dist/index.js
// src/nix.ts
function makeNixCommandArgs(nixOptions, flakeInputs, commitMessage) {
function makeNixCommandArgs(nixOptions, flakeInputs) {
const flakeInputFlags = flakeInputs.flatMap((input) => [
"--update-input",
input
]);
const lockfileSummaryFlags = [
"--option",
"commit-lockfile-summary",
commitMessage
];
const updateLockMechanism = flakeInputFlags.length === 0 ? "update" : "lock";
return nixOptions.concat(["flake", updateLockMechanism]).concat(flakeInputFlags).concat(["--commit-lock-file"]).concat(lockfileSummaryFlags);
return nixOptions.concat(["flake", updateLockMechanism]).concat(flakeInputFlags);
}

// src/index.ts




var EVENT_EXECUTION_FAILURE = "execution_failure";
var COMMIT_MESSAGE_MAX_LENGTH = 65536;
var UpdateFlakeLockAction = class extends DetSysAction {
constructor() {
super({
name: "update-flake-lock",
fetchStyle: "universal",
requireNix: "fail"
});
this.commitMessage = inputs_exports.getString("commit-msg");
this.flakeInputs = inputs_exports.getArrayOfStrings("inputs", "space");
this.nixOptions = inputs_exports.getArrayOfStrings("nix-options", "space");
this.pathToFlakeDir = inputs_exports.getStringOrNull("path-to-flake-dir");
Expand All @@ -95291,20 +95289,25 @@ var UpdateFlakeLockAction = class extends DetSysAction {
async update() {
const nixCommandArgs = makeNixCommandArgs(
this.nixOptions,
this.flakeInputs,
this.commitMessage
this.flakeInputs
);
core.debug(
JSON.stringify({
options: this.nixOptions,
inputs: this.flakeInputs,
message: this.commitMessage,
args: nixCommandArgs
})
);
let output = "";
const execOptions = {
cwd: this.pathToFlakeDir !== null ? this.pathToFlakeDir : void 0,
ignoreReturnCode: true
ignoreReturnCode: true,
outStream: new external_stream_.Writable({
write: (chunk, _, callback) => {
output += chunk.toString();
callback();
}
})
};
const exitCode = await exec.exec("nix", nixCommandArgs, execOptions);
if (exitCode !== 0) {
Expand All @@ -95314,6 +95317,15 @@ var UpdateFlakeLockAction = class extends DetSysAction {
core.setFailed(`non-zero exit code of ${exitCode} detected`);
} else {
core.info(`flake.lock file was successfully updated`);
if (output.length > COMMIT_MESSAGE_MAX_LENGTH) {
core.warning(
`commit message is too long, truncating to ${COMMIT_MESSAGE_MAX_LENGTH} characters`
);
}
core.exportVariable(
"FLAKE_UPDATE_OUTPUT",
output.trim().slice(0, COMMIT_MESSAGE_MAX_LENGTH)
);
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 22 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { makeNixCommandArgs } from "./nix.js";
import * as actionsCore from "@actions/core";
import * as actionsExec from "@actions/exec";
import { DetSysAction, inputs } from "detsys-ts";
import { Writable } from "stream";

const EVENT_EXECUTION_FAILURE = "execution_failure";
const COMMIT_MESSAGE_MAX_LENGTH = 65536;

class UpdateFlakeLockAction extends DetSysAction {
private commitMessage: string;
private nixOptions: string[];
private flakeInputs: string[];
private pathToFlakeDir: string | null;
Expand All @@ -18,7 +19,6 @@ class UpdateFlakeLockAction extends DetSysAction {
requireNix: "fail",
});

this.commitMessage = inputs.getString("commit-msg");
this.flakeInputs = inputs.getArrayOfStrings("inputs", "space");
this.nixOptions = inputs.getArrayOfStrings("nix-options", "space");
this.pathToFlakeDir = inputs.getStringOrNull("path-to-flake-dir");
Expand All @@ -33,28 +33,34 @@ class UpdateFlakeLockAction extends DetSysAction {

async update(): Promise<void> {
// 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}
// nix ${maybe nix options} flake ${"update" or "lock"} ${maybe --update-input flags}
// 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"
// nix --extra-substituters https://example.com flake lock --update-input nixpkgs
// nix flake update
const nixCommandArgs: string[] = makeNixCommandArgs(
this.nixOptions,
this.flakeInputs,
this.commitMessage,
);

actionsCore.debug(
JSON.stringify({
options: this.nixOptions,
inputs: this.flakeInputs,
message: this.commitMessage,
args: nixCommandArgs,
}),
);

let output = "";

const execOptions: actionsExec.ExecOptions = {
cwd: this.pathToFlakeDir !== null ? this.pathToFlakeDir : undefined,
ignoreReturnCode: true,
outStream: new Writable({
Copy link
Author

@hackardoX hackardoX Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of this, I tried to use:

const {exitCode, stdout} = await actionsExec.getExecOutput("nix", nixCommandArgs, execOptions);

but the stdout was empty

write: (chunk, _, callback) => {
output += chunk.toString();
callback();
},
}),
};

const exitCode = await actionsExec.exec("nix", nixCommandArgs, execOptions);
Expand All @@ -66,6 +72,15 @@ class UpdateFlakeLockAction extends DetSysAction {
actionsCore.setFailed(`non-zero exit code of ${exitCode} detected`);
} else {
actionsCore.info(`flake.lock file was successfully updated`);
if (output.length > COMMIT_MESSAGE_MAX_LENGTH) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a safety net in the case the flake output is too huge (it can happen if we have plenty of outdated flakes as dependencies)

actionsCore.warning(
`commit message is too long, truncating to ${COMMIT_MESSAGE_MAX_LENGTH} characters`,
);
}
actionsCore.exportVariable(
"FLAKE_UPDATE_OUTPUT",
output.trim().slice(0, COMMIT_MESSAGE_MAX_LENGTH),
);
}
}
}
Expand Down
Loading