Skip to content
Merged
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
22 changes: 19 additions & 3 deletions .github/actions/terragrunt-plan/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ outputs:
diff:
description: "Whether the plan is out of sync"
value: ${{ steps.plan.outputs.diff }}
diff-hosts:
description: "The hosts that are out of sync"
value: ${{ steps.plan.outputs.diff-hosts }}

runs:
using: "composite"
Expand All @@ -30,12 +33,24 @@ runs:
>(sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g' >> "$GITHUB_OUTPUT")
echo "$delimiter" >> "$GITHUB_OUTPUT"

diff="$(terragrunt run-all show -json | jq -s '
diff_file="$(mktemp)"
trap 'rm -f "$diff_file"' EXIT
terragrunt run-all show -json > "$diff_file"

diff="$(jq -s '
[.[].resource_changes[]?.change.actions[]?]
+ [.[].output_changes[]?.actions[]?]
| any(. != "no-op")
')"
' < "$diff_file")"
diff_hosts="$(jq -sc '
[.[].resource_changes[]?
| select([.change.actions[]?] | any(. != "no-op"))
| .address
| capture("^module\\.nixos_deploy\\[\"(?<host>\\w+)\"\\].shell_script.deploy$")
| .host]
' < "$diff_file")"
echo "diff=$diff" >> "$GITHUB_OUTPUT"
echo "diff-hosts=$diff_hosts" >> "$GITHUB_OUTPUT"
working-directory: ${{ inputs.working-directory }}
env:
TG_OUT_DIR: ${{ github.workspace }}/.data/tfplans
Expand All @@ -46,7 +61,7 @@ runs:
### Terragrunt Plan :memo:

<details>
<summary>Terragrunt Log/summary>
<summary>Terragrunt Plan Log</summary>

```text
${{ steps.plan.outputs.plan }}
Expand All @@ -55,6 +70,7 @@ runs:
</details>

**Status**: ${{ steps.plan.outputs.diff == 'true' && 'out of sync :warning:' || 'no changes :ok_hand:' }}
**Hosts to deploy**: ${{ join(fromJSON(steps.plan.outputs.diff-hosts), ', ') }}
EOF
- name: Pack tfplans
if: steps.plan.outputs.diff == 'true' && inputs.skip-upload != 'true'
Expand Down
76 changes: 75 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ jobs:
permissions:
id-token: write # for AWS and Aliyun OIDC federation
pull-requests: write # for updating the PR comment
outputs:
diff-hosts: ${{ steps.plan.outputs.diff-hosts }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
Expand All @@ -63,7 +65,6 @@ jobs:
id: plan
with:
skip-upload: "true"
# Update the comment
- uses: peter-evans/find-comment@v3
id: find-comment
with:
Expand All @@ -77,10 +78,83 @@ jobs:
body: |
### Terragrunt Plan :memo:

<details>
<summary>Terragrunt Plan Logs</summary>

```text
${{ steps.plan.outputs.plan }}
```

</details>

**Status**: ${{ steps.plan.outputs.diff == 'true' && 'out of sync :warning:' || 'no changes :ok_hand:' }}
**Hosts to deploy**: ${{ join(fromJSON(steps.plan.outputs.diff-hosts), ', ') }}
token: ${{ secrets.GITHUB_TOKEN }}
edit-mode: replace

diff:
runs-on: nixos-x86_64-linux
needs: plan
strategy:
matrix:
host: ${{ fromJson(needs.plan.outputs.diff-hosts) }}
permissions:
pull-requests: write # for updating the PR comment
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
with:
components: api-token,attic,ssh,devshell
api-token: ${{ secrets.GITHUB_TOKEN }}
attic-token: ${{ secrets.ATTIC_TOKEN }}
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Push and diff "${{ matrix.host }}"
shell: bash
id: diff
run: |
deployment=$(nix eval ".#deploy" --impure --json --apply 'd:
(n: n // { profiles = null; } // n.profiles.system)
(d // { nodes = null; } // d.nodes."${builtins.getEnv "HOST"}")')
deploy --ssh-opts "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
--skip-checks --debug-logs --dry-activate ".#$HOST"
readarray -d '' ssh_opts < <(
jq --raw-output0 '.sshOpts[]?, "\(.sshUser // "root")@\(.hostname)"' <<<"$deployment")
new_system=$(nix derivation show ".#nixosConfigurations.$HOST.config.system.build.toplevel" |
jq -rc '.[].outputs.out.path')
delimiter="$({ tr -dc A-Za-z0-9 </dev/urandom || true; } | head -c 13)"

echo "diff<<$delimiter" >> "$GITHUB_OUTPUT"
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "${ssh_opts[@]}" -- \
nix store diff-closures /run/current-system "$new_system" |& tee \
>(sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g' >> "$GITHUB_OUTPUT")
echo "$delimiter" >> "$GITHUB_OUTPUT"
env:
HOST: ${{ matrix.host }}
- name: Summarize diff
shell: bash
run: |
cat <<'EOF' >> "$GITHUB_STEP_SUMMARY"
### Changes for Host ${{ matrix.host }} :rocket:

```text
${{ steps.diff.outputs.diff }}
```
EOF
- uses: peter-evans/find-comment@v3
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: "github-actions[bot]"
body-includes: "### Changes for Host ${{ matrix.host }}"
- uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Changes for Host ${{ matrix.host }} :rocket:

```text
${{ steps.diff.outputs.diff }}
```
token: ${{ secrets.GITHUB_TOKEN }}
edit-mode: replace
36 changes: 18 additions & 18 deletions flake.lock

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

2 changes: 1 addition & 1 deletion terraform/modules/nixos_deploy/create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ set -euo pipefail

cd "$WORKING_DIRECTORY"
deploy --ssh-opts "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
--skip-checks --auto-rollback false "$FLAKE#$NODE" -- --print-build-logs
--skip-checks --debug-logs --auto-rollback false "$FLAKE#$NODE"
echo -n '{"done": true}'