Merge remote-tracking branch 'origin/main'
# Conflicts: # .github/workflows/release.yml
This commit is contained in:
+165
-283
@@ -8,9 +8,9 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
bump_type:
|
||||
description: 'Specify the type of version bump'
|
||||
description: "Specify the type of version bump"
|
||||
required: true
|
||||
default: 'patch'
|
||||
default: "patch"
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Commitizen
|
||||
run: |
|
||||
@@ -126,9 +126,7 @@ jobs:
|
||||
- name: Generate changelog for the version bump
|
||||
id: changelog
|
||||
run: |
|
||||
changelog=$(conventional-changelog -p angular -i CHANGELOG.md -s --from ${{ env.prev_version }} --to ${{ env.version }})
|
||||
echo "$changelog" > artifacts/changelog.md
|
||||
echo "changelog_body=$(cat artifacts/changelog.md)" >> $GITHUB_ENV
|
||||
conventional-changelog -p conventionalcommits -i CHANGELOG.md --from ${{ env.prev_version }} --to v${{ env.version }} > artifacts/changelog.md
|
||||
|
||||
- name: Push changes
|
||||
if: env.ACT != 'true'
|
||||
@@ -151,30 +149,42 @@ jobs:
|
||||
Cargo.toml
|
||||
Cargo.lock
|
||||
|
||||
build-release-artifacts:
|
||||
publish-github-release:
|
||||
name: build-release
|
||||
needs: [bump-version]
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
BUILD_CMD: cargo
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
# prettier-ignore
|
||||
job:
|
||||
# - { name: "macOS-arm64", os: "macOS-latest", target: "aarch64-apple-darwin", artifact_suffix: "macos-arm64", use-cross: true }
|
||||
# - { name: "macOS-amd64", os: "macOS-latest", target: "x86_64-apple-darwin", artifact_suffix: "macos" }
|
||||
# - { name: "windows-amd64", os: "windows-latest", target: "x86_64-pc-windows-msvc", artifact_suffix: "windows" }
|
||||
# - { name: "windows-aarch64", os: "windows-latest", target: "aarch64-pc-windows-msvc", artifact_suffix: "windows-aarch64", use-cross: true }
|
||||
- { name: "linux-gnu", os: "ubuntu-latest", target: "x86_64-unknown-linux-gnu", artifact_suffix: "linux" }
|
||||
- { name: "linux-musl", os: "ubuntu-latest", target: "x86_64-unknown-linux-musl", artifact_suffix: "linux-musl", use-cross: true, }
|
||||
# - { name: "linux-aarch64-gnu", os: "ubuntu-latest", target: "aarch64-unknown-linux-gnu", artifact_suffix: "aarch64-gnu", use-cross: true, test-bin: "--bin gman" }
|
||||
# - { name: "linux-aarch64-musl", os: "ubuntu-latest", target: "aarch64-unknown-linux-musl", artifact_suffix: "aarch64-musl", use-cross: true, test-bin: "--bin gman" }
|
||||
# - { name: "linux-arm-gnu", os: "ubuntu-latest", target: "arm-unknown-linux-gnueabi", artifact_suffix: "armv6-gnu", use-cross: true, test-bin: "--bin gman" }
|
||||
# - { name: "linux-arm-musl", os: "ubuntu-latest", target: "arm-unknown-linux-musleabihf", artifact_suffix: "armv6-musl", use-cross: true, test-bin: "--bin gman" }
|
||||
# - { name: "linux-armv7-gnu", os: "ubuntu-latest", target: "armv7-unknown-linux-gnueabihf", artifact_suffix: "armv7-gnu", use-cross: true, test-bin: "--bin gman" }
|
||||
# - { name: "linux-armv7-musl", os: "ubuntu-latest", target: "armv7-unknown-linux-musleabihf", artifact_suffix: "armv7-musl", use-cross: true, test-bin: "--bin gman" }
|
||||
rust: [stable]
|
||||
include:
|
||||
- target: aarch64-unknown-linux-musl
|
||||
os: ubuntu-latest
|
||||
use-cross: true
|
||||
cargo-flags: ""
|
||||
- target: aarch64-apple-darwin
|
||||
os: macos-latest
|
||||
use-cross: true
|
||||
cargo-flags: ""
|
||||
- target: aarch64-pc-windows-msvc
|
||||
os: windows-latest
|
||||
use-cross: true
|
||||
cargo-flags: ""
|
||||
- target: x86_64-apple-darwin
|
||||
os: macos-latest
|
||||
cargo-flags: ""
|
||||
- target: x86_64-pc-windows-msvc
|
||||
os: windows-latest
|
||||
cargo-flags: ""
|
||||
- target: x86_64-unknown-linux-musl
|
||||
os: ubuntu-latest
|
||||
use-cross: true
|
||||
cargo-flags: ""
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
os: ubuntu-latest
|
||||
cargo-flags: ""
|
||||
|
||||
steps:
|
||||
- name: Check if actor is repository owner
|
||||
@@ -194,216 +204,6 @@ jobs:
|
||||
git fetch --all
|
||||
git pull
|
||||
|
||||
- name: Get bumped Cargo files (Act)
|
||||
if: env.ACT == 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: bumped-cargo-files
|
||||
path: ${{ github.workspace }}
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Cache Cargo registry
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
|
||||
|
||||
- uses: actions/cache@v3
|
||||
if: startsWith(matrix.job.name, 'linux-')
|
||||
with:
|
||||
path: ~/.cargo/bin
|
||||
key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/release.yml') }}
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
name: Set Rust toolchain
|
||||
with:
|
||||
targets: ${{ matrix.job.target }}
|
||||
|
||||
- uses: taiki-e/setup-cross-toolchain-action@v1
|
||||
with:
|
||||
# NB: sets CARGO_BUILD_TARGET evar - do not need --target flag in build
|
||||
target: ${{ matrix.job.target }}
|
||||
|
||||
- uses: taiki-e/install-action@cross
|
||||
if: ${{ matrix.job.use-cross }}
|
||||
|
||||
- name: Installing needed Ubuntu dependencies
|
||||
if: matrix.job.os == 'ubuntu-latest'
|
||||
shell: bash
|
||||
run: |
|
||||
rustup update
|
||||
sudo apt-get -y update
|
||||
case ${{ matrix.job.target }} in
|
||||
arm*-linux-*) sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
|
||||
aarch64-*-linux-*) sudo apt-get -y install gcc-aarch64-linux-gnu ;;
|
||||
esac
|
||||
|
||||
- name: Install clang + bindgen for musl targets
|
||||
if: matrix.job.os == 'ubuntu-latest' && contains(matrix.job.target, 'musl')
|
||||
shell: bash
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install clang llvm-dev libclang-dev pkg-config cmake make build-essential musl-tools
|
||||
# force install to avoid stale cache issues
|
||||
cargo install --force --locked bindgen-cli
|
||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
# help bindgen find libclang
|
||||
echo "LIBCLANG_PATH=$(llvm-config --libdir)" >> "$GITHUB_ENV"
|
||||
# quick visibility checks (fail early if missing)
|
||||
which bindgen
|
||||
bindgen --version
|
||||
clang --version
|
||||
|
||||
- name: Configure bindgen target flags for musl cross-compile
|
||||
if: matrix.job.os == 'ubuntu-latest' && contains(matrix.job.target, 'musl')
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
triple='${{ matrix.job.target }}'
|
||||
# Bindgen needs explicit target to avoid host header confusion
|
||||
echo "BINDGEN_EXTRA_CLANG_ARGS_${triple//-/_}=--target=$triple" >> "$GITHUB_ENV"
|
||||
# CC hints help any C sub-builds in the tree
|
||||
case "$triple" in
|
||||
x86_64-unknown-linux-musl)
|
||||
echo "CC_x86_64_unknown_linux_musl=musl-gcc" >> "$GITHUB_ENV"
|
||||
;;
|
||||
aarch64-unknown-linux-musl)
|
||||
echo "CC_aarch64_unknown_linux_musl=aarch64-linux-musl-gcc" >> "$GITHUB_ENV"
|
||||
;;
|
||||
arm-unknown-linux-musleabihf)
|
||||
echo "CC_arm_unknown_linux_musleabihf=arm-linux-musleabihf-gcc" >> "$GITHUB_ENV"
|
||||
;;
|
||||
armv7-unknown-linux-musleabihf)
|
||||
echo "CC_armv7_unknown_linux_musleabihf=armv7-linux-musleabihf-gcc" >> "$GITHUB_ENV"
|
||||
;;
|
||||
esac
|
||||
echo "PKG_CONFIG_ALLOW_CROSS=1" >> "$GITHUB_ENV"
|
||||
|
||||
- name: OpenSSL (vendored) toolchain for musl
|
||||
if: startsWith(matrix.job.name, 'linux-') && contains(matrix.job.target, 'musl')
|
||||
shell: bash
|
||||
run: |
|
||||
# Tools needed for building vendored OpenSSL
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install musl-tools pkg-config perl make cmake
|
||||
|
||||
# Let openssl-sys know we're cross-compiling and want static
|
||||
echo "OPENSSL_STATIC=1" >> $GITHUB_ENV
|
||||
echo "PKG_CONFIG_ALLOW_CROSS=1" >> $GITHUB_ENV
|
||||
|
||||
# Set the right C compiler per musl target (some provided by taiki-e/setup-cross-toolchain-action)
|
||||
case "${{ matrix.job.target }}" in
|
||||
x86_64-unknown-linux-musl)
|
||||
echo "CC_x86_64_unknown_linux_musl=musl-gcc" >> $GITHUB_ENV
|
||||
;;
|
||||
aarch64-unknown-linux-musl)
|
||||
# If your toolchain action installs aarch64-linux-musl-gcc, use that:
|
||||
echo "CC_aarch64_unknown_linux_musl=aarch64-linux-musl-gcc" >> $GITHUB_ENV
|
||||
;;
|
||||
arm-unknown-linux-musleabihf)
|
||||
echo "CC_arm_unknown_linux_musleabihf=arm-linux-musleabihf-gcc" >> $GITHUB_ENV
|
||||
;;
|
||||
armv7-unknown-linux-musleabihf)
|
||||
echo "CC_armv7_unknown_linux_musleabihf=armv7-linux-musleabihf-gcc" >> $GITHUB_ENV
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
if [[ "${{ matrix.job.use-cross || 'false' }}" == 'true' ]]; then
|
||||
cross build --release --locked --target=${{ matrix.job.target }} --verbose
|
||||
else
|
||||
cargo build --release --locked --target=${{ matrix.job.target }} --verbose
|
||||
fi
|
||||
|
||||
- name: Verify file
|
||||
shell: bash
|
||||
run: |
|
||||
file target/${{ matrix.job.target }}/release/gman
|
||||
|
||||
- name: Test
|
||||
if: matrix.job.target != 'aarch64-apple-darwin' && matrix.job.target != 'aarch64-pc-windows-msvc'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
if [[ "${{ matrix.job.use-cross || 'false' }}" == 'true' ]]; then
|
||||
cross test --release --locked --target=${{ matrix.job.target }} --verbose ${{ matrix.job.test-bin }}
|
||||
else
|
||||
cargo test --release --locked --target=${{ matrix.job.target }} --verbose ${{ matrix.job.test-bin }}
|
||||
fi
|
||||
|
||||
- name: Test
|
||||
if: matrix.job.target != 'aarch64-apple-darwin' && matrix.job.target != 'aarch64-pc-windows-msvc'
|
||||
run: cargo test --release --verbose --target=${{ matrix.job.target }} ${{ matrix.job.test-bin }}
|
||||
|
||||
- name: Packaging final binary (Windows)
|
||||
if: matrix.job.os == 'windows-latest'
|
||||
shell: bash
|
||||
run: |
|
||||
cd target/${{ matrix.job.target }}/release
|
||||
BINARY_NAME=gman.exe
|
||||
if [ "${{ matrix.job.target }}" != "aarch64-pc-windows-msvc" ]; then
|
||||
# strip the binary
|
||||
strip $BINARY_NAME
|
||||
fi
|
||||
RELEASE_NAME=gman-${{ matrix.job.artifact_suffix }}
|
||||
mkdir -p artifacts
|
||||
tar czvf $RELEASE_NAME.tar.gz $BINARY_NAME
|
||||
# create sha checksum files
|
||||
certutil -hashfile $RELEASE_NAME.tar.gz sha256 | grep -E [A-Fa-f0-9]{64} > $RELEASE_NAME.sha256
|
||||
echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV
|
||||
|
||||
- name: Packaging final binary (macOS and Linux)
|
||||
if: matrix.job.os != 'windows-latest'
|
||||
shell: bash
|
||||
run: |
|
||||
# set the right strip executable
|
||||
STRIP="strip";
|
||||
case ${{ matrix.job.target }} in
|
||||
arm*-linux-*) STRIP="arm-linux-gnueabihf-strip" ;;
|
||||
aarch64-*-linux-*) STRIP="aarch64-linux-gnu-strip" ;;
|
||||
esac;
|
||||
cd target/${{ matrix.job.target }}/release
|
||||
BINARY_NAME=gman
|
||||
# strip the binary
|
||||
"$STRIP" "$BINARY_NAME"
|
||||
RELEASE_NAME=gman-${{ matrix.job.artifact_suffix }}
|
||||
tar czvf $RELEASE_NAME.tar.gz $BINARY_NAME
|
||||
# create sha checksum files
|
||||
shasum -a 256 $RELEASE_NAME.tar.gz > $RELEASE_NAME.sha256
|
||||
echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV
|
||||
|
||||
- name: Add artifacts
|
||||
run: |
|
||||
mkdir -p artifacts
|
||||
cp target/${{ matrix.job.target }}/release/${{ env.RELEASE_NAME }}.tar.gz artifacts/
|
||||
cp target/${{ matrix.job.target }}/release/${{ env.RELEASE_NAME }}.sha256 artifacts/
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: artifacts-${{ env.RELEASE_NAME }}
|
||||
path: artifacts
|
||||
overwrite: true
|
||||
|
||||
publish-github-release:
|
||||
name: publish-github-release
|
||||
needs: [build-release-artifacts]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if actor is repository owner
|
||||
if: ${{ github.actor != github.repository_owner && env.ACT != 'true' }}
|
||||
run: |
|
||||
echo "You are not authorized to run this workflow."
|
||||
exit 1
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
@@ -417,60 +217,146 @@ jobs:
|
||||
git pull
|
||||
|
||||
- name: Set environment variables
|
||||
shell: bash
|
||||
run: |
|
||||
release_version="$(cat ./artifacts/release-version)"
|
||||
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
||||
changelog_body="$(cat ./artifacts/changelog.md)"
|
||||
echo "changelog_body=$(cat artifacts/changelog.md)" >> $GITHUB_ENV
|
||||
|
||||
- name: Validate release environment variables
|
||||
run: |
|
||||
echo "Release version: ${{ env.RELEASE_VERSION }}"
|
||||
echo "Changelog body: ${{ env.changelog_body }}"
|
||||
echo "Changelog body: $(cat artifacts/changelog.md)"
|
||||
|
||||
- name: Create a GitHub Release
|
||||
- name: Get bumped Cargo files (Act)
|
||||
if: env.ACT == 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: bumped-cargo-files
|
||||
path: ${{ github.workspace }}
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
name: Set Rust toolchain
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Install cross
|
||||
if: matrix.use-cross
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cross
|
||||
|
||||
- name: Overwrite build command env variable
|
||||
if: matrix.use-cross
|
||||
shell: bash
|
||||
run: echo "BUILD_CMD=cross" >> $GITHUB_ENV
|
||||
|
||||
- name: Install latest LLVM/Clang
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
# omit the version to get the latest stable for your Ubuntu (24.04 "noble" on ubuntu-latest)
|
||||
sudo ./llvm.sh all
|
||||
# ensure libclang dev package is present (adjust the "22" if a newer major exists)
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libclang-20-dev libclang-dev
|
||||
|
||||
- name: Show Version Information (Rust, cargo, GCC)
|
||||
shell: bash
|
||||
run: |
|
||||
gcc --version || true
|
||||
rustup -V
|
||||
rustup toolchain list
|
||||
rustup default
|
||||
cargo -V
|
||||
rustc -V
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: $BUILD_CMD build --locked --release --target=${{ matrix.target }} ${{ matrix.cargo-flags }}
|
||||
|
||||
- name: Verify file
|
||||
shell: bash
|
||||
run: |
|
||||
file target/${{ matrix.target }}/release/gman
|
||||
|
||||
- name: Test
|
||||
if: matrix.target != 'aarch64-apple-darwin' && matrix.target != 'aarch64-pc-windows-msvc'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
if [[ "${{ matrix.use-cross || 'false' }}" == 'true' ]]; then
|
||||
cross test --release --locked --target=${{ matrix.target }} --verbose
|
||||
else
|
||||
cargo test --release --locked --target=${{ matrix.target }} --verbose
|
||||
fi
|
||||
|
||||
- name: Build Archive
|
||||
shell: bash
|
||||
id: package
|
||||
env:
|
||||
target: ${{ matrix.target }}
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
|
||||
bin=${GITHUB_REPOSITORY##*/}
|
||||
dist_dir=`pwd`/dist
|
||||
name=$bin-$target
|
||||
executable=target/$target/release/$bin
|
||||
|
||||
if [[ "$RUNNER_OS" == "Windows" ]]; then
|
||||
executable=$executable.exe
|
||||
fi
|
||||
|
||||
mkdir $dist_dir
|
||||
cp $executable $dist_dir
|
||||
cd $dist_dir
|
||||
|
||||
if [[ "$RUNNER_OS" == "Windows" ]]; then
|
||||
archive=$dist_dir/$name.zip
|
||||
sha=$dist_dir/$name.sha256
|
||||
7z a $archive *
|
||||
certutil -hashfile $archive sha256 | grep -E [A-Fa-f0-9]{64} > $sha
|
||||
echo "archive=dist/$name.zip" >> $GITHUB_OUTPUT
|
||||
echo "sha=dist/$name.sha256" >> $GITHUB_OUTPUT
|
||||
else
|
||||
archive=$dist_dir/$name.tar.gz
|
||||
sha=$dist_dir/$name.sha256
|
||||
tar -czf $archive *
|
||||
shasum -a 256 $archive > $sha
|
||||
echo "archive=dist/$name.tar.gz" >> $GITHUB_OUTPUT
|
||||
echo "sha=dist/$name.sha256" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Publish Archive and SHA
|
||||
if: env.ACT != 'true'
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: |
|
||||
artifacts/gman-macos-arm64.tar.gz
|
||||
artifacts/gman-macos-arm64.sha256
|
||||
artifacts/gman-macos.tar.gz
|
||||
artifacts/gman-macos.sha256
|
||||
artifacts/gman-windows.tar.gz
|
||||
artifacts/gman-windows.sha256
|
||||
artifacts/gman-windows-aarch64.tar.gz
|
||||
artifacts/gman-windows-aarch64.sha256
|
||||
artifacts/gman-linux.tar.gz
|
||||
artifacts/gman-linux.sha256
|
||||
artifacts/gman-linux-musl.tar.gz
|
||||
artifacts/gman-linux-musl.sha256
|
||||
artifacts/gman-aarch64-gnu.tar.gz
|
||||
artifacts/gman-aarch64-gnu.sha256
|
||||
artifacts/gman-aarch64-musl.tar.gz
|
||||
artifacts/gman-aarch64-musl.sha256
|
||||
artifacts/gman-armv6-gnu.tar.gz
|
||||
artifacts/gman-armv6-gnu.sha256
|
||||
artifacts/gman-armv6-musl.tar.gz
|
||||
artifacts/gman-armv6-musl.sha256
|
||||
artifacts/gman-armv7-gnu.tar.gz
|
||||
artifacts/gman-armv7-gnu.sha256
|
||||
artifacts/gman-armv7-musl.tar.gz
|
||||
artifacts/gman-armv7-musl.sha256
|
||||
${{ steps.package.outputs.archive }}
|
||||
${{ steps.package.outputs.sha }}
|
||||
tag_name: v${{ env.RELEASE_VERSION }}
|
||||
name: 'v${{ env.RELEASE_VERSION }}'
|
||||
body: ${{ env.changelog_body }}
|
||||
draft: false
|
||||
name: "v${{ env.RELEASE_VERSION }}"
|
||||
body_path: artifacts/changelog.md
|
||||
prerelease: false
|
||||
|
||||
- name: Add artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
[[ -d artifacts ]] || mkdir -p artifacts
|
||||
cp ${{ steps.package.outputs.archive }} artifacts/
|
||||
cp ${{ steps.package.outputs.sha }} artifacts/
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: artifacts-v${{ env.RELEASE_VERSION }}-${{ matrix.target }}
|
||||
path: artifacts
|
||||
overwrite: true
|
||||
|
||||
|
||||
publish-chocolatey-package:
|
||||
needs: [publish-github-release]
|
||||
name: Publish Chocolatey Package
|
||||
@@ -497,7 +383,7 @@ jobs:
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Read the first column from the SHA256 file
|
||||
$windows_sha = Get-Content ./artifacts/gman-windows.sha256 | ForEach-Object { $_.Split(' ')[0] }
|
||||
$windows_sha = Get-Content ./artifacts/gman-x86_64-pc-windows-msvc.sha256 | ForEach-Object { $_.Split(' ')[0] }
|
||||
Add-Content -Path $env:GITHUB_ENV -Value "WINDOWS_SHA=$windows_sha"
|
||||
|
||||
# Read the release version from the release-version file
|
||||
@@ -520,10 +406,17 @@ jobs:
|
||||
# Publish to Chocolatey
|
||||
cd ./deployment/chocolatey
|
||||
choco pack
|
||||
echo y | choco install gman -dv -s .
|
||||
$version = gman --version
|
||||
choco install gman --yes -dv -s .
|
||||
# Verify install succeeded
|
||||
choco list --local-only | Select-String '^gman ' | Out-Null
|
||||
|
||||
# Run the EXE directly from the installed package folder
|
||||
$exe = Get-ChildItem "$env:ChocolateyInstall\lib\gman\tools\gman*.exe" -ErrorAction Stop |
|
||||
Select-Object -First 1 -ExpandProperty FullName
|
||||
|
||||
$version = & $exe --version
|
||||
$version = $version -replace " ", "."
|
||||
choco push $version.nupkg -s https://push.chocolatey.org/ --api-key ${{ secrets.CHOCOLATEY_API_KEY }};
|
||||
choco push "$version.nupkg" -s https://push.chocolatey.org/ --api-key ${{ secrets.CHOCOLATEY_API_KEY }}
|
||||
|
||||
publish-homebrew-formula:
|
||||
needs: [publish-github-release]
|
||||
@@ -551,11 +444,11 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
# Set environment variables
|
||||
macos_sha="$(cat ./artifacts/gman-macos.sha256 | awk '{print $1}')"
|
||||
macos_sha="$(cat ./artifacts/gman-x86_64-apple-darwin.sha256 | awk '{print $1}')"
|
||||
echo "MACOS_SHA=$macos_sha" >> $GITHUB_ENV
|
||||
macos_sha_arm="$(cat ./artifacts/gman-macos-arm64.sha256 | awk '{print $1}')"
|
||||
macos_sha_arm="$(cat ./artifacts/gman-aarch64-apple-darwin.sha256 | awk '{print $1}')"
|
||||
echo "MACOS_SHA_ARM=$macos_sha_arm" >> $GITHUB_ENV
|
||||
linux_sha="$(cat ./artifacts/gman-linux-musl.sha256 | awk '{print $1}')"
|
||||
linux_sha="$(cat ./artifacts/gman-x86_64-unknown-linux-musl.sha256 | awk '{print $1}')"
|
||||
echo "LINUX_SHA=$linux_sha" >> $GITHUB_ENV
|
||||
release_version="$(cat ./artifacts/release-version)"
|
||||
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
||||
@@ -618,17 +511,6 @@ jobs:
|
||||
git fetch --all
|
||||
git pull
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Cache Cargo registry
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cargo/bin
|
||||
key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/release.yml') }}
|
||||
|
||||
- name: Install Rust stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
|
||||
+33
-1
@@ -7,4 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [0.0.1] - 2025-09-10
|
||||
|
||||
### Other
|
||||
## v0.1.0 (2025-09-15)
|
||||
|
||||
### Fix
|
||||
|
||||
- Pass the changelog to the GHA properly using a file
|
||||
- Potential bug in changelog variable generation
|
||||
- Revert back hacky stuff so I can test with act now
|
||||
- Attempting to use pre-generated bindgens for the aws-lc-sys library
|
||||
- Install openSSL differently to make this work
|
||||
- Address edge case for unknown_musl targets
|
||||
- Install LLVM prereqs for release flow
|
||||
- Updated the release flow to install the external bindgen-cli
|
||||
|
||||
## v0.0.1 (2025-09-12)
|
||||
|
||||
### Feat
|
||||
|
||||
- Azure Key Vault support
|
||||
- GCP Secret Manager support
|
||||
- Full AWS SecretsManager support
|
||||
- AWS Secrets Manager support
|
||||
- Added two new flags to output where gman writes logs to and where it expects the config file to live
|
||||
|
||||
### Fix
|
||||
|
||||
- Made the vault file location more fault tolerant
|
||||
- Attempting to maybe be a bit more explicit about config file handling to fix MacOS tests
|
||||
|
||||
### Refactor
|
||||
|
||||
- Refactor configuration structs directly into the provider definition to simplify validation, structs, and future extensions
|
||||
- Made the creation of the log directories a bit more fault tolerant
|
||||
- Renamed the provider field in a config file to type to make things a little easier to understand; also removed husky
|
||||
|
||||
Generated
+25
-15
@@ -1501,9 +1501,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gcloud-sdk"
|
||||
version = "0.28.1"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41dcccf7c0cc0986cb5f476854a5c63b95bab4835f12884704f6aa33ac7d14bc"
|
||||
checksum = "7fe603014c94ee883f514ea12a3df0ad99da67124472bd3c52ee7fed0ccd4ea1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@@ -1576,7 +1576,7 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
||||
|
||||
[[package]]
|
||||
name = "gman"
|
||||
version = "0.0.1"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -1605,7 +1605,6 @@ dependencies = [
|
||||
"log",
|
||||
"log4rs",
|
||||
"openssl",
|
||||
"openssl-sys",
|
||||
"predicates",
|
||||
"pretty_assertions",
|
||||
"proptest",
|
||||
@@ -2206,9 +2205,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
|
||||
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
@@ -3291,16 +3290,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
version = "1.0.223"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
checksum = "a505d71960adde88e293da5cb5eda57093379f64e61cf77bf0e6a63af07a7bac"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
@@ -3315,10 +3315,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
name = "serde_core"
|
||||
version = "1.0.223"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
checksum = "20f57cbd357666aa7b3ac84a90b4ea328f1d4ddb6772b430caa5d9e1309bb9e9"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.223"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d428d07faf17e306e699ec1e91996e5a165ba5d6bce5b5155173e91a8a01a56"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3327,14 +3336,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.143"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+7
-3
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "gman"
|
||||
version = "0.0.1"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
||||
description = "Universal secret management and injection tool"
|
||||
@@ -58,10 +58,14 @@ gcloud-sdk = { version = "0.28.1", features = [
|
||||
crc32c = "0.6.8"
|
||||
azure_identity = "0.27.0"
|
||||
azure_security_keyvault_secrets = "0.6.0"
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
openssl-sys = { version = "0.9", features = ["vendored"] }
|
||||
aws-lc-sys = { version = "0.31.0", features = ["bindgen"] }
|
||||
|
||||
[target.'cfg(all(target_os="linux", target_env="musl"))'.dependencies]
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
|
||||
[target.'cfg(target_os="macos")'.dependencies]
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.1"
|
||||
proptest = "1.5.0"
|
||||
|
||||
@@ -2,7 +2,7 @@ $ErrorActionPreference = 'Stop';
|
||||
|
||||
$PackageName = 'gman'
|
||||
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
||||
$url64 = 'https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-windows.tar.gz'
|
||||
$url64 = 'https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-x86_64-pc-windows-msvc.zip'
|
||||
$checksum64 = '$hash_64'
|
||||
|
||||
$packageArgs = @{
|
||||
@@ -16,5 +16,5 @@ $packageArgs = @{
|
||||
|
||||
}
|
||||
Install-ChocolateyZipPackage @packageArgs
|
||||
$File = Get-ChildItem -File -Path $env:ChocolateyInstall\lib\$packageName\tools\ -Filter *.tar
|
||||
$File = Get-ChildItem -File -Path $env:ChocolateyInstall\lib\$packageName\tools\ -Filter *.zip
|
||||
Get-ChocolateyUnzip -fileFullPath $File.FullName -destination $env:ChocolateyInstall\lib\$packageName\tools\
|
||||
|
||||
@@ -33,9 +33,9 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe
|
||||
<docsUrl>https://github.com/Dark-Alex-17/gman/blob/main/README.md</docsUrl>
|
||||
<bugTrackerUrl>https://github.com/Dark-Alex-17/gman/issues</bugTrackerUrl>
|
||||
<tags>cli cross-platform terminal credential-management secret-management rust</tags>
|
||||
<summary>Universal command line credential management and injection tool</summary>
|
||||
<summary>Universal CLI credential management and injection tool</summary>
|
||||
<description>
|
||||
Universal command line credential management and injection tool.
|
||||
Universal CLI credential management and injection tool.
|
||||
|
||||
**Usage**
|
||||
To get started, run `gman --help` in a terminal.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
||||
# https://rubydoc.brew.sh/Formula
|
||||
class GMan < Formula
|
||||
class Gman < Formula
|
||||
desc "Universal command line credential management and injection tool"
|
||||
homepage "https://github.com/Dark-Alex-17/gman"
|
||||
if OS.mac? and Hardware::CPU.arm?
|
||||
url "https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-macos-arm64.tar.gz"
|
||||
url "https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-aarch64-apple-darwin.tar.gz"
|
||||
sha256 "$hash_mac_arm"
|
||||
elsif OS.mac? and Hardware::CPU.intel?
|
||||
url "https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-macos.tar.gz"
|
||||
url "https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "$hash_mac"
|
||||
else
|
||||
url "https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-linux-musl.tar.gz"
|
||||
url "https://github.com/Dark-Alex-17/gman/releases/download/v$version/gman-x86_64-unknown-linux-musl.tar.gz"
|
||||
sha256 "$hash_linux"
|
||||
end
|
||||
version "$version"
|
||||
|
||||
@@ -144,6 +144,7 @@ impl ProviderConfig {
|
||||
match &mut self.provider_type {
|
||||
SupportedProvider::Local { provider_def } => {
|
||||
debug!("Using local secret provider");
|
||||
provider_def.runtime_provider_name = self.name.clone();
|
||||
provider_def
|
||||
}
|
||||
SupportedProvider::AwsSecretsManager { provider_def } => {
|
||||
|
||||
+143
-6
@@ -5,9 +5,9 @@ use std::path::{Path, PathBuf};
|
||||
use std::{env, fs};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::providers::SecretProvider;
|
||||
use crate::config::{Config, get_config_file_path, load_config};
|
||||
use crate::providers::git_sync::{SyncOpts, repo_name_from_url, sync_and_push};
|
||||
use crate::providers::{SecretProvider, SupportedProvider};
|
||||
use crate::{
|
||||
ARGON_M_COST_KIB, ARGON_P, ARGON_T_COST, HEADER, KDF, KEY_LEN, NONCE_LEN, SALT_LEN, VERSION,
|
||||
};
|
||||
@@ -54,6 +54,8 @@ pub struct LocalProvider {
|
||||
#[validate(email)]
|
||||
pub git_user_email: Option<String>,
|
||||
pub git_executable: Option<PathBuf>,
|
||||
#[serde(skip)]
|
||||
pub runtime_provider_name: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for LocalProvider {
|
||||
@@ -65,6 +67,7 @@ impl Default for LocalProvider {
|
||||
git_user_name: None,
|
||||
git_user_email: None,
|
||||
git_executable: None,
|
||||
runtime_provider_name: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,7 +172,9 @@ impl SecretProvider for LocalProvider {
|
||||
config_changed = true;
|
||||
debug!("Prompting user to set git_remote in config for sync");
|
||||
let remote: String = Input::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt("Enter remote git URL to sync with")
|
||||
.with_prompt(
|
||||
"Enter remote git URL to sync with (e.g. 'git@github.com:user/repo.git')",
|
||||
)
|
||||
.validate_with(|s: &String| {
|
||||
LocalProvider {
|
||||
git_remote_url: Some(s.clone()),
|
||||
@@ -185,9 +190,7 @@ impl SecretProvider for LocalProvider {
|
||||
}
|
||||
|
||||
if config_changed {
|
||||
debug!("Saving updated config");
|
||||
confy::store("gman", "config", &self)
|
||||
.with_context(|| "failed to save updated config")?;
|
||||
self.persist_git_settings_to_config()?;
|
||||
}
|
||||
|
||||
let sync_opts = SyncOpts {
|
||||
@@ -203,6 +206,52 @@ impl SecretProvider for LocalProvider {
|
||||
}
|
||||
|
||||
impl LocalProvider {
|
||||
fn persist_git_settings_to_config(&self) -> Result<()> {
|
||||
debug!("Saving updated config (only current local provider)");
|
||||
|
||||
let mut cfg = load_config().with_context(|| "failed to load existing config")?;
|
||||
|
||||
let target_name = self.runtime_provider_name.clone();
|
||||
let mut updated = false;
|
||||
for pc in cfg.providers.iter_mut() {
|
||||
if let SupportedProvider::Local { provider_def } = &mut pc.provider_type {
|
||||
let matches_name = match (&pc.name, &target_name) {
|
||||
(Some(n), Some(t)) => n == t,
|
||||
(Some(_), None) => false,
|
||||
_ => false,
|
||||
};
|
||||
if matches_name || target_name.is_none() {
|
||||
provider_def.git_branch = self.git_branch.clone();
|
||||
provider_def.git_remote_url = self.git_remote_url.clone();
|
||||
|
||||
updated = true;
|
||||
if matches_name {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !updated {
|
||||
bail!("unable to find matching local provider in config to update");
|
||||
}
|
||||
|
||||
let path = get_config_file_path()?;
|
||||
let ext = path.extension().and_then(|s| s.to_str()).unwrap_or("");
|
||||
if ext.eq_ignore_ascii_case("yml") || ext.eq_ignore_ascii_case("yaml") {
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
let s = serde_yaml::to_string(&cfg)?;
|
||||
fs::write(&path, s).with_context(|| format!("failed to write {}", path.display()))?;
|
||||
} else {
|
||||
confy::store("gman", "config", &cfg)
|
||||
.with_context(|| "failed to save updated config via confy")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn repo_dir_for_config(&self) -> Result<Option<PathBuf>> {
|
||||
if let Some(remote) = &self.git_remote_url {
|
||||
let name = repo_name_from_url(remote);
|
||||
@@ -424,6 +473,7 @@ mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
use secrecy::{ExposeSecret, SecretString};
|
||||
use std::env as std_env;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[test]
|
||||
@@ -458,9 +508,96 @@ mod tests {
|
||||
fs::write(&file, "secretpw\n").unwrap();
|
||||
let provider = LocalProvider {
|
||||
password_file: Some(file),
|
||||
runtime_provider_name: None,
|
||||
..LocalProvider::default()
|
||||
};
|
||||
let pw = provider.get_password().unwrap();
|
||||
assert_eq!(pw.expose_secret(), "secretpw");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn persist_only_target_local_provider_git_settings() {
|
||||
let td = tempdir().unwrap();
|
||||
let xdg = td.path().join("xdg");
|
||||
let app_dir = xdg.join("gman");
|
||||
fs::create_dir_all(&app_dir).unwrap();
|
||||
unsafe {
|
||||
std_env::set_var("XDG_CONFIG_HOME", &xdg);
|
||||
}
|
||||
|
||||
let initial_yaml = indoc::indoc! {
|
||||
"---
|
||||
default_provider: local
|
||||
providers:
|
||||
- name: local
|
||||
type: local
|
||||
password_file: /tmp/.gman_pass
|
||||
git_branch: main
|
||||
git_remote_url: null
|
||||
git_user_name: null
|
||||
git_user_email: null
|
||||
git_executable: null
|
||||
- name: other
|
||||
type: local
|
||||
git_branch: main
|
||||
git_remote_url: git@github.com:someone/else.git
|
||||
run_configs:
|
||||
- name: echo
|
||||
secrets: [API_KEY]
|
||||
"
|
||||
};
|
||||
let cfg_path = app_dir.join("config.yml");
|
||||
fs::write(&cfg_path, initial_yaml).unwrap();
|
||||
|
||||
let provider = LocalProvider {
|
||||
password_file: None,
|
||||
git_branch: Some("dev".into()),
|
||||
git_remote_url: Some("git@github.com:user/repo.git".into()),
|
||||
git_user_name: Some("Test User".into()),
|
||||
git_user_email: Some("test@example.com".into()),
|
||||
git_executable: Some(PathBuf::from("/usr/bin/git")),
|
||||
runtime_provider_name: Some("local".into()),
|
||||
};
|
||||
|
||||
provider
|
||||
.persist_git_settings_to_config()
|
||||
.expect("persist ok");
|
||||
|
||||
let content = fs::read_to_string(&cfg_path).unwrap();
|
||||
let cfg: crate::config::Config = serde_yaml::from_str(&content).unwrap();
|
||||
|
||||
assert_eq!(cfg.default_provider.as_deref(), Some("local"));
|
||||
assert!(cfg.run_configs.is_some());
|
||||
assert_eq!(cfg.run_configs.as_ref().unwrap().len(), 1);
|
||||
|
||||
let p0 = &cfg.providers[0];
|
||||
assert_eq!(p0.name.as_deref(), Some("local"));
|
||||
match &p0.provider_type {
|
||||
SupportedProvider::Local { provider_def } => {
|
||||
assert_eq!(provider_def.git_branch.as_deref(), Some("dev"));
|
||||
assert_eq!(
|
||||
provider_def.git_remote_url.as_deref(),
|
||||
Some("git@github.com:user/repo.git")
|
||||
);
|
||||
}
|
||||
_ => panic!("expected local provider"),
|
||||
}
|
||||
|
||||
let p1 = &cfg.providers[1];
|
||||
assert_eq!(p1.name.as_deref(), Some("other"));
|
||||
match &p1.provider_type {
|
||||
SupportedProvider::Local { provider_def } => {
|
||||
assert_eq!(provider_def.git_branch.as_deref(), Some("main"));
|
||||
assert_eq!(
|
||||
provider_def.git_remote_url.as_deref(),
|
||||
Some("git@github.com:someone/else.git")
|
||||
);
|
||||
}
|
||||
_ => panic!("expected local provider"),
|
||||
}
|
||||
|
||||
unsafe {
|
||||
std_env::remove_var("XDG_CONFIG_HOME");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ fn test_local_provider_valid() {
|
||||
git_user_name: None,
|
||||
git_user_email: Some("test@example.com".to_string()),
|
||||
git_executable: None,
|
||||
runtime_provider_name: None,
|
||||
};
|
||||
|
||||
assert!(provider.validate().is_ok());
|
||||
@@ -48,6 +49,7 @@ fn test_local_provider_invalid_email() {
|
||||
git_user_name: None,
|
||||
git_user_email: Some("test".to_string()),
|
||||
git_executable: None,
|
||||
runtime_provider_name: None,
|
||||
};
|
||||
|
||||
assert!(config.validate().is_err());
|
||||
|
||||
Reference in New Issue
Block a user