Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make terra plan write diff to github PR #383

Merged
merged 5 commits into from
Nov 12, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
mac:
uses: ./.github/workflows/std.yml
with:
runs-on: macOS-12
runs-on: macOS-13
secrets: inherit

linux:
Expand Down
8 changes: 4 additions & 4 deletions src/local/flake.lock

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

17 changes: 8 additions & 9 deletions src/std/fwlib/actions/build-proviso.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
declare action="$1"
declare targetDrv

eval "$(jq -r '@sh "targetDrv=\(.targetDrv)"' <<< "$action" )"
eval "$(jq -r '@sh "targetDrv=\(.targetDrv)"' <<<"$action")"

mapfile -t uncached < <(
command nix-store --realise --dry-run "$targetDrv" 2>&1 1>/dev/null \
| command sed -nr '
command nix-store --realise --dry-run "$targetDrv" 2>&1 1>/dev/null |
command sed -nE '
# If the line "will be built" is matched ...
/will be built/ {
# Create a label to iterate over dervivations
Expand All @@ -28,18 +28,17 @@ mapfile -t uncached < <(
'
)

if [[ ${#uncached[@]} -eq 0 ]];
then
if [[ ${#uncached[@]} -eq 0 ]]; then
exit 1
fi

if ! (
command nix show-derivation ''${uncached[@]} 2> /dev/null \
| command jq --exit-status \
' with_entries(
command nix show-derivation ''${uncached[@]} 2>/dev/null |
command jq --exit-status \
' with_entries(
select(.value|.env.preferLocalBuild != "1")
) | any
' 1> /dev/null
' 1>/dev/null
); then
exit 1
fi
Expand Down
70 changes: 70 additions & 0 deletions src/std/fwlib/blockTypes/_postDiffToGitHubSnippet.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
_: marker: diff_output: summary: ''
if [[ -v CI ]] && [[ -v BRANCH ]] && [[ -v OWNER_AND_REPO ]] && command -v gh > /dev/null ; then

OWNER_REPO_NAME=$(gh repo view "$OWNER_AND_REPO" --json nameWithOwner --jq '.nameWithOwner')

if ! gh pr view "$BRANCH" --repo "$OWNER_REPO_NAME" >/dev/null 2>&1; then
exit 0
fi

# Proceed only if there is output
if [[ -z "${diff_output}" ]]; then
exit 0
fi

CENTRAL_COMMENT_HEADER="<!-- Unified Diff Comment -->"
ENTRY_START_MARKER="<!-- Start Diff for ${marker} -->"
ENTRY_END_MARKER="<!-- End Diff for ${marker} -->"

# Use the provided summary
DIFF_ENTRY=$(cat <<EOF

$ENTRY_START_MARKER
<details>
<summary>${summary}</summary>

\`\`\`diff
${diff_output}
\`\`\`

</details>
$ENTRY_END_MARKER
EOF
)

PR_NUMBER=$(gh pr view "$BRANCH" --repo "$OWNER_REPO_NAME" --json number --jq '.number')

EXISTING_COMMENT_ID=$(gh api "repos/$OWNER_REPO_NAME/issues/$PR_NUMBER/comments?per_page=100" --jq ".[] | select(.body | contains(\"$CENTRAL_COMMENT_HEADER\")) | .id" | head -n 1)

if [[ -n "$EXISTING_COMMENT_ID" ]]; then
EXISTING_BODY=$(gh api "repos/$OWNER_REPO_NAME/issues/comments/$EXISTING_COMMENT_ID" --jq '.body')

if echo "$EXISTING_BODY" | grep -q "$ENTRY_START_MARKER"; then
UPDATED_BODY=$(echo "$EXISTING_BODY" | sed -e "\#$ENTRY_START_MARKER#,\#$ENTRY_END_MARKER#d")
else
UPDATED_BODY="$EXISTING_BODY"
fi

UPDATED_BODY="$UPDATED_BODY
$DIFF_ENTRY"

echo "Updating existing comment..."
gh api --method PATCH "repos/$OWNER_REPO_NAME/issues/comments/$EXISTING_COMMENT_ID" -f body="$UPDATED_BODY" --jq '.html_url'

else
NEW_COMMENT=$(cat <<EOF
$CENTRAL_COMMENT_HEADER
## DiffPost

This PR includes the following diffs:
$DIFF_ENTRY
EOF
)
echo "Creating new comment..."
gh pr comment "$PR_NUMBER" --repo "$OWNER_REPO_NAME" --body "$NEW_COMMENT"
fi

exit 0

fi
''
33 changes: 5 additions & 28 deletions src/std/fwlib/blockTypes/kubectl.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Available actions:
*/
let
inherit (root) mkCommand;
inherit (super) addSelectorFunctor askUserToProceedSnippet;
inherit (super) addSelectorFunctor askUserToProceedSnippet postDiffToGitHubSnippet;
in
name: {
__functor = addSelectorFunctor;
Expand Down Expand Up @@ -137,34 +137,11 @@ in
} "$manifest_path/";
}

# GitHub case
if [[ -v CI ]] && [[ -v BRANCH ]] && [[ -v OWNER_AND_REPO ]] && command gh > /dev/null ; then
${postDiffToGitHubSnippet "${fragmentRelPath}:diff" "$(diff || true)" "<code>std ${fragmentRelPath}:diff</code>"}

set +e # diff exits 1 if diff existed
read -r -d "" DIFFSTREAM <<DIFF
## Standard DiffPost

This PR would generate the following \`kubectl\` diff:

<details><summary>Preview</summary>

\`\`\`diff
$(diff)
\`\`\`

</details>
DIFF
set -e # we're past the invocation of diff

if ! gh pr --repo "$OWNER_AND_REPO" comment "$BRANCH" --edit-last -b "$DIFFSTREAM"; then
echo "Make a first post ..."
gh pr --repo "$OWNER_AND_REPO" comment "$BRANCH" -b "$DIFFSTREAM"
fi
else
KUBECTL_EXTERNAL_DIFF="icdiff -N -r"
export KUBECTL_EXTERNAL_DIFF
diff
fi
KUBECTL_EXTERNAL_DIFF="icdiff -N -r"
export KUBECTL_EXTERNAL_DIFF
diff
'' {})
(mkCommand currentSystem "apply" "Apply the manifests to K8s" [pkgs.kubectl pkgs.icdiff] ''
${build}
Expand Down
2 changes: 1 addition & 1 deletion src/std/fwlib/blockTypes/nvfetcher.nix
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ in
--changelog "$tmpfile" \
--filter "^$targetname$"

sed -i -e "s|^|- \`$(date --iso-8601=m)\` |" "$tmpfile"
sed -i '''' -e "s|^|- \`$(date --iso-8601=m)\` |" "$tmpfile"
cat "$tmpfile" >> "$updates"
'' {})
];
Expand Down
34 changes: 22 additions & 12 deletions src/std/fwlib/blockTypes/terra.nix
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ Available actions:
*/
let
inherit (root) mkCommand;
inherit (super) addSelectorFunctor;
inherit (super) addSelectorFunctor postDiffToGitHubSnippet;
in
name: repo: {
inherit name;
__functor = self: selectors: self // selectors;
__functor = addSelectorFunctor;
type = "terra";
actions = {
currentSystem,
Expand All @@ -37,12 +37,8 @@ in
inherit (inputs) terranix;
pkgs = inputs.nixpkgs.${currentSystem};

repoFolder = with pkgs.lib;
concatStringsSep "/" (["./nix"] ++ (init (splitString "/" fragmentRelPath)));

git = {
inherit repo;
# repo = "[email protected]:myorg/myrepo.git";
ref = "main";
state = fragmentRelPath + "/state.json";
};
Expand All @@ -60,32 +56,46 @@ in
.config);

setup = ''
export TF_VAR_fragment=${pkgs.lib.strings.escapeShellArg fragment}
export TF_VAR_fragmentRelPath=${fragmentRelPath}
export TF_IN_AUTOMATION=1
# export TF_INPUT=0
export TF_DATA_DIR="$PRJ_DATA_HOME/${fragmentRelPath}"
export TF_PLUGIN_CACHE_DIR="$PRJ_CACHE_HOME/tf-plugin-cache"
mkdir -p "$TF_DATA_DIR"
mkdir -p "$TF_PLUGIN_CACHE_DIR"
dir="$PRJ_ROOT/${repoFolder}/.tf"
mkdir -p "$PRJ_ROOT/${repoFolder}/.tf"
cat << MESSAGE > "$PRJ_ROOT/${repoFolder}/.tf/readme.md"
dir="$PRJ_ROOT/.tf/${fragmentRelPath}/.tf"
mkdir -p "$dir"
cat << MESSAGE > "$dir/readme.md"
This is a tf staging area.
It is motivated by the terraform CLI requiring to be executed in a staging area.
MESSAGE

if [[ -e "$dir/config.tf.json" ]]; then rm -f "$dir/config.tf.json"; fi
jq '.' ${terraformConfiguration} > "$dir/config.tf.json"
'';

wrap = cmd: ''
${setup}

# Run the command and capture output
terraform-backend-git git \
--dir "$dir" \
--repository ${git.repo} \
--ref ${git.ref} \
--state ${git.state} \
terraform ${cmd} "$@";
terraform ${cmd} "$@" \
${pkgs.lib.optionalString (cmd == "plan") ''
-lock=false -no-color | tee "$PRJ_CACHE_HOME/tf.console.txt"
''}

# Pass output to the snippet
${pkgs.lib.optionalString (cmd == "plan") ''
output=$(cat "$PRJ_CACHE_HOME/tf.console.txt")
summary_plan=$(tac "$PRJ_CACHE_HOME/tf.console.txt" | grep -m 1 -E '^(Error:|Plan:|Apply complete!|No changes.|Success)' | tac || echo "View output.")
summary="<code>std ${fragmentRelPath}:${cmd}</code>: $summary_plan"
${postDiffToGitHubSnippet "${fragmentRelPath}:${cmd}" "$output" "$summary"}
''}
'';

in [
(mkCommand currentSystem "init" "tf init" [pkgs.jq pkgs.terraform pkgs.terraform-backend-git] (wrap "init") {})
(mkCommand currentSystem "plan" "tf plan" [pkgs.jq pkgs.terraform pkgs.terraform-backend-git] (wrap "plan") {})
Expand Down
16 changes: 8 additions & 8 deletions src/tests/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 src/tests/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
terranix.inputs.terranix-examples.follows = "";
terranix.inputs.bats-support.follows = "";
terranix.inputs.bats-assert.follows = "";
namaka.url = "github:nix-community/namaka/v0.2.0";
namaka.url = "github:nix-community/namaka/ecefdd6d1e0e075403a69202c2695f966ea2f412";
namaka.inputs.haumea.follows = "std/haumea";
namaka.inputs.nixpkgs.follows = "std/nixpkgs";
makes.url = "github:fluidattacks/makes";
Expand Down
2 changes: 1 addition & 1 deletion tests/_snapshots/check-augmented-cell-inputs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
makes = "/nix/store/71rzg7vs53gmxqph64d9zqf4ns928c6c-source";
microvm = "/nix/store/v5za7dzczgcvfvqgcm80qari3msyhw6b-source";
n2c = "/nix/store/rgd4s5ylv38p94wi6vays6wc1a0l5iyf-source";
namaka = "/nix/store/xgzvi3baaaz9lpymfv6f1fgxfmy0ygvv-source";
namaka = "/nix/store/prb836vl3r64l97045clfli0d5m5fyap-source";
nixago = "/nix/store/cys15p6lyyhj85bk4bckn82waih2l945-source";
nixpkgs = "/nix/store/g8zzlf6drg73c987ii390yicq4c0j778-source";
paisano = "/nix/store/4v8nn2z2vl74yz1557n1dha3l7rzzbgs-source";
Expand Down
Loading