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
27 changes: 27 additions & 0 deletions .github/PSScriptAnalyzerSettings.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# PSScriptAnalyzer configuration for the CI lint gate.
#
# This is the PowerShell counterpart to the shellcheck job that already guards install-guard.sh.
# The Windows installer had no static analysis at all, which is how a WMI cmdlet removed in
# PowerShell 6 sat in it unnoticed -- the CI shell is pwsh 7, so nothing in the repository would
# have caught it before a user did.
#
# The gate runs with every default rule enabled except the exclusion below, so a new finding fails
# the build rather than accumulating.
@{
Severity = @('Error', 'Warning', 'Information')

ExcludeRules = @(
# PSAvoidUsingWriteHost objects to Write-Host because its output cannot be captured or
# redirected, which is the right call for a module or a library returning data to a caller.
# install-guard.ps1 is neither: it is an interactive installer whose output is progress
# commentary for a human watching a terminal, and the README documents piping it straight
# into Invoke-Expression. Write-Output would put that commentary into the pipeline, where
# it would be mistaken for the return value of the functions that emit it -- Get-ArchType
# and Get-GuardVersion both return values by writing to the pipeline, so mixing progress
# text into it would actively break them.
#
# Suppressed here rather than per-line: it applies to every Write-Host in the file for the
# same reason, and twenty-odd inline suppressions would obscure the code they annotate.
'PSAvoidUsingWriteHost'
)
}
113 changes: 106 additions & 7 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ jobs:
- name: Shellcheck
run: shellcheck install-guard.sh

# The PowerShell counterpart to shellcheck. install-guard.ps1 had no static analysis, which is
# how a WMI cmdlet that PowerShell 6 removed sat in it unnoticed -- this workflow runs pwsh 7,
# so nothing here would have caught it before a user did. Configured by
# .github/PSScriptAnalyzerSettings.psd1; runs on ubuntu because the analyser is
# platform independent and a Linux runner is cheaper than a Windows one.
psscriptanalyzer:
name: PSScriptAnalyzer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install PSScriptAnalyzer
shell: pwsh
run: Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -Force -AcceptLicense
- name: Analyze install-guard.ps1
shell: pwsh
run: |
$findings = Invoke-ScriptAnalyzer -Path install-guard.ps1 `
-Settings .github/PSScriptAnalyzerSettings.psd1
if ($findings) {
$findings | Format-Table -AutoSize Severity, Line, RuleName, Message | Out-String -Width 200 | Write-Host
throw "PSScriptAnalyzer reported $($findings.Count) finding(s)"
}
Write-Host "PSScriptAnalyzer: no findings"

formatting:
name: Formatting check (cargo fmt)
runs-on: ubuntu-latest
Expand All @@ -53,35 +77,110 @@ jobs:
- name: Rustfmt Check
uses: actions-rust-lang/rustfmt@v1

# These jobs install a binary built from the branch under test, not the last published release.
#
# They used to resolve "latest release" from the GitHub API and install that, which tested the
# installer against a binary having nothing to do with the change under review, and made the job
# depend on an API whose anonymous limit is 60 requests per hour per source IP -- shared across
# every job on a runner. That limit is what failed the Windows job on an unrelated pull request.
#
# Packaging the local build into the release layout and pointing the installer at it with
# GUARD_DOWNLOAD_BASE_URL removes the network from the critical path and makes the assertion
# meaningful: the checksum of the installed binary is compared against the one just built.
#
# GITHUB_TOKEN is still exported. Nothing in the pinned path needs it, but any future step that
# resolves a version should be authenticated by default rather than discover the limit in CI.
installScript:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: Testing Install Script (install-guard.sh)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
name: Checkout cfn-guard
with:
path: cloudformation-guard
- name: Test install script on ${{ matrix.os }}
- uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Build cfn-guard from this branch
working-directory: cloudformation-guard
run: cargo build --release --bin cfn-guard
- name: Package the build into the release layout and install it
working-directory: cloudformation-guard
run: |
set -e
cd cloudformation-guard
sh install-guard.sh
set -eu
VERSION=$(./target/release/cfn-guard --version | awk '{ print $2 }')
MAJOR=${VERSION%%.*}
case "$(uname -s)" in
Darwin) OS_TYPE=macos ;;
*) OS_TYPE=ubuntu ;;
esac
ARCH_TYPE=$(uname -m)
[ "$ARCH_TYPE" = "arm64" ] && ARCH_TYPE=aarch64
NAME="cfn-guard-v${MAJOR}-${ARCH_TYPE}-${OS_TYPE}-latest"

mkdir -p "stage/${NAME}" "artifacts/${VERSION}"
cp target/release/cfn-guard "stage/${NAME}/cfn-guard"
tar -czf "artifacts/${VERSION}/${NAME}.tar.gz" -C stage "${NAME}"

GUARD_DOWNLOAD_BASE_URL="file://${PWD}/artifacts" sh install-guard.sh -v "${VERSION}"

# The installer reports success on its own terms; this checks it installed the binary we
# just built rather than something already on the runner.
"${HOME}/.guard/bin/cfn-guard" --version
BUILT=$(shasum -a 256 target/release/cfn-guard | awk '{ print $1 }')
INSTALLED=$(shasum -a 256 "${HOME}/.guard/${MAJOR}/${NAME}/cfn-guard" | awk '{ print $1 }')
if [ "$BUILT" != "$INSTALLED" ]; then
echo "installed binary does not match the one built from this branch" >&2
echo " built: $BUILT" >&2
echo " installed: $INSTALLED" >&2
exit 1
fi
echo "installed binary matches this branch's build ($BUILT)"

installScriptWindows:
runs-on: windows-latest
name: Testing Windows Install Script (install-guard.ps1)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
name: Checkout cfn-guard
with:
path: cloudformation-guard
- name: Test install script on windows-latest
- uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Build cfn-guard from this branch
working-directory: cloudformation-guard
run: cargo build --release --bin cfn-guard
- name: Package the build into the release layout and install it
working-directory: cloudformation-guard
shell: pwsh
run: |
cd cloudformation-guard
./install-guard.ps1
$ErrorActionPreference = 'Stop'
$version = (& ./target/release/cfn-guard.exe --version).Split(' ')[1]
$major = $version.Split('.')[0]
$arch = switch ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) {
'Arm64' { 'aarch64' } 'X64' { 'x86_64' } 'X86' { 'i686' }
}
$name = "cfn-guard-v$major-$arch-windows-latest"

New-Item -ItemType Directory -Force -Path "stage/$name", "artifacts/$version" | Out-Null
Copy-Item target/release/cfn-guard.exe "stage/$name/cfn-guard.exe"
tar -czf "artifacts/$version/$name.tar.gz" -C stage $name

$env:GUARD_DOWNLOAD_BASE_URL = "file://$($PWD.Path -replace '\\','/')/artifacts"
./install-guard.ps1 -Version $version

# The installer reports success on its own terms; this checks it installed the binary we
# just built rather than something already on the runner.
$built = (Get-FileHash target/release/cfn-guard.exe -Algorithm SHA256).Hash
$installed = (Get-FileHash "$env:USERPROFILE\.guard\$major\$name\cfn-guard.exe" -Algorithm SHA256).Hash
if ($built -ne $installed) {
throw "installed binary ($installed) does not match this branch's build ($built)"
}
Write-Host "installed binary matches this branch's build ($built)"

linting:
name: Linting check (clippy)
Expand Down
76 changes: 0 additions & 76 deletions guard/src/commands/aws_meta_appender.rs

This file was deleted.

86 changes: 0 additions & 86 deletions guard/src/commands/aws_meta_appender_tests.rs

This file was deleted.

27 changes: 0 additions & 27 deletions guard/src/commands/common_test_helpers.rs

This file was deleted.

2 changes: 1 addition & 1 deletion guard/src/commands/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ where
}
}

pub(crate) fn iterate_over<T, C>(files: &[PathBuf], converter: C) -> Iter<T, C>
pub(crate) fn iterate_over<T, C>(files: &[PathBuf], converter: C) -> Iter<'_, T, C>
where
C: Fn(String, &PathBuf) -> Result<T, Error>,
{
Expand Down
3 changes: 0 additions & 3 deletions guard/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ pub mod rulegen;
pub mod test;
pub mod validate;

mod aws_meta_appender;
mod common_test_helpers;
pub mod completions;
pub mod reporters;
mod tracker;

//
// Constants
Expand Down
Loading