Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
433a9e7
Migrate dotfile deployment from Dotbot to chezmoi
jsilverdev Oct 3, 2026
74e3a4f
Fix chezmoi source name for zshrc
jsilverdev Oct 3, 2026
06da6f9
Persist local chezmoi source during bootstrap
jsilverdev Oct 3, 2026
36c0f02
Install chezmoi from pacman on Arch
jsilverdev Oct 3, 2026
58fe7c2
Add post-migration CI validation
jsilverdev Oct 3, 2026
3584eb5
Fix CI runtime policy and container setup
jsilverdev Oct 3, 2026
02779a7
Fix CI checkout depth and diagnostics
jsilverdev Oct 3, 2026
76ff76c
Fix CI remote checks and syntax validation
jsilverdev Oct 3, 2026
67bcea3
Stabilize Linux updates and AllSigned checks
jsilverdev Oct 3, 2026
89305a8
Fix Windows command steps and container Git safety
jsilverdev Oct 3, 2026
e7b27e4
Fix container remote ownership and AllSigned command flow
jsilverdev Oct 3, 2026
ce35776
Harden CI update and PowerShell policy setup
jsilverdev Oct 3, 2026
3cf5a1d
Fix ga actions
jsilverdev Oct 3, 2026
852d7ff
Fix CI fixtures and AllSigned verification
jsilverdev Oct 3, 2026
6c364ce
Fix PowerShell bridge named arguments
jsilverdev Oct 3, 2026
18689c2
Keep PowerShell bridge below CMD limit
jsilverdev Oct 3, 2026
8309df3
Stabilize Windows core CI validation
jsilverdev Oct 3, 2026
37c0a40
Preserve Windows PATH and preprovision signing cert
jsilverdev Oct 3, 2026
8a3e20a
Split Windows bootstrap validation phases
jsilverdev Oct 3, 2026
adbfeff
Unblock revised CI validation run
jsilverdev Oct 3, 2026
1100843
Make Windows CI fully non-interactive
jsilverdev Oct 3, 2026
7f96857
Fix post-apply PowerShell path binding
jsilverdev Oct 3, 2026
185213b
Remove remaining Windows CI prompts
jsilverdev Oct 3, 2026
3eaa419
Keep Starship in Windows core setup
jsilverdev Oct 3, 2026
600a14d
Isolate Windows runtime and add AllSigned fallback
jsilverdev Oct 3, 2026
e21d735
Separate direct and bridged Windows installer checks
jsilverdev Oct 3, 2026
6cee063
Use mise state for core Starship check
jsilverdev Oct 3, 2026
518c4f7
Fix Windows CI path and enforce AllSigned validation
jsilverdev Oct 4, 2026
0c9512b
Fix Windows chezmoi status assertions
jsilverdev Oct 4, 2026
4f4f3c6
Fix Windows state semantics and AllSigned CI trust
jsilverdev Oct 4, 2026
4f9554f
Install Windows core CLI toolchain
jsilverdev Oct 4, 2026
d710d61
Keep core WinGet installs scope-neutral
jsilverdev Oct 4, 2026
f6b4819
Split Windows CI diagnostics
jsilverdev Oct 4, 2026
5756e89
Refine Windows CI diagnostics
jsilverdev Oct 4, 2026
81a4162
Fix Windows EOL state and AllSigned bridge
jsilverdev Oct 4, 2026
51f6c5a
Route normal Windows scripts directly through pwsh
jsilverdev Oct 4, 2026
b4b2a04
Refine Windows update and AllSigned checks
jsilverdev Oct 4, 2026
27d0463
Fix AllSigned signer args and WinGet no-update handling
jsilverdev Oct 4, 2026
d22629f
Skip WinGet upgrades when no update is available
jsilverdev Oct 4, 2026
13a094e
Run AllSigned signing helper as a Windows PowerShell script
jsilverdev Oct 4, 2026
7646af1
Make code-signing EKU validation host-independent
jsilverdev Oct 4, 2026
22acd09
Expose AllSigned bootstrap failure stage
jsilverdev Oct 4, 2026
b61ba02
Map AllSigned bootstrap failure stages
jsilverdev Oct 4, 2026
70a2046
Run AllSigned bootstrap diagnostics through CMD
jsilverdev Oct 4, 2026
b78c666
Isolate AllSigned chezmoi initialization failures
jsilverdev Oct 4, 2026
70c02f1
Restore certificate provider in nested AllSigned bridge
jsilverdev Oct 4, 2026
f8af7a6
Provision PowerShell modules safely under AllSigned
jsilverdev Oct 4, 2026
93f44f7
Avoid PowerShell Security autoload under AllSigned
jsilverdev Oct 4, 2026
ace94f9
Make AllSigned assertions security-module independent
jsilverdev Oct 4, 2026
022d7d1
Fix AllSigned Authenticode assertion parsing
jsilverdev Oct 4, 2026
3274a12
Harden AllSigned PSReadLine and native process checks
jsilverdev Oct 4, 2026
61849c0
Re-sign managed modules with the trusted publisher
jsilverdev Oct 4, 2026
469c2b6
Refactor dotfiles CI and bootstrap validation
jsilverdev Oct 4, 2026
a4f02bd
Document refactored test suite
jsilverdev Oct 4, 2026
44098d9
Fix refactored Linux and AllSigned validation
jsilverdev Oct 4, 2026
7bdf94f
Remove redundant unsigned-script probe
jsilverdev Oct 4, 2026
1ec3b7c
Simplify installer modes and validate real baseline
jsilverdev Oct 4, 2026
8d92197
Fix baseline validation and managed module updates
jsilverdev Oct 4, 2026
dfb9f70
Split static source validation phases
jsilverdev Oct 4, 2026
008ecd6
Make static architecture checks explicit
jsilverdev Oct 4, 2026
887805b
Make architecture validation deterministic
jsilverdev Oct 4, 2026
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
1 change: 1 addition & 0 deletions .chezmoiroot
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
home
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto eol=lf
*.cmd text eol=crlf
157 changes: 157 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
name: Validate dotfiles

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: validate-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
static:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- name: Install validation tools
shell: bash
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install --yes --no-install-recommends shellcheck
mkdir -p "$RUNNER_TEMP/bin"
curl -fsLS https://get.chezmoi.io | sh -s -- -b "$RUNNER_TEMP/bin"

actionlint_version=1.7.12
actionlint_archive="$RUNNER_TEMP/actionlint.tar.gz"
curl -fsSL "https://github.com/rhysd/actionlint/releases/download/v${actionlint_version}/actionlint_${actionlint_version}_linux_amd64.tar.gz" -o "$actionlint_archive"
echo "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 $actionlint_archive" | sha256sum --check
tar -xzf "$actionlint_archive" -C "$RUNNER_TEMP/bin" actionlint
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"

- name: Validate workflow
run: actionlint .github/workflows/validate.yml

- name: Validate shell source
run: bash tests/static/validate-source.sh shell

- name: Validate chezmoi source
run: bash tests/static/validate-source.sh chezmoi

- name: Validate source architecture
run: python3 tests/static/validate-architecture.py

- name: Validate manifests
run: python3 tests/static/validate-manifests.py

- name: Validate encoded PowerShell bridge
run: python3 tests/static/check-powershell-bridge.py

- name: Validate PowerShell syntax
shell: pwsh
run: ./tests/static/validate-powershell.ps1

linux:
name: linux-${{ matrix.distro }}
runs-on: ubuntu-24.04
timeout-minutes: 35
strategy:
fail-fast: false
matrix:
include:
- distro: debian
image: debian:bookworm-slim
- distro: arch
image: archlinux:base
container:
image: ${{ matrix.image }}
steps:
- name: Prepare container
shell: sh
run: |
set -eu
case "${{ matrix.distro }}" in
debian) apt-get update; apt-get install --yes --no-install-recommends ca-certificates curl git sudo bash ;;
arch) pacman -Sy --noconfirm ca-certificates curl git sudo bash ;;
esac

- uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false

- name: Exercise bootstrap and update
run: bash tests/linux/run-ci.sh "${{ matrix.distro }}" "$GITHUB_SHA"

windows:
runs-on: windows-2025
timeout-minutes: 45
env:
DOTFILES_NONINTERACTIVE: "1"
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false
- shell: pwsh
run: ./tests/windows/prepare-ci.ps1
- name: Run bootstrap
shell: cmd
run: |
mkdir "%RUNNER_TEMP%\dotfiles-run" 2>nul
pushd "%RUNNER_TEMP%\dotfiles-run"
call "%GITHUB_WORKSPACE%\bootstrap.cmd"
set "E=%ERRORLEVEL%"
popd
exit /b %E%
- shell: pwsh
run: ./tests/windows/assert-state.ps1 -RepoRoot $env:GITHUB_WORKSPACE -ExpectedCommit $env:GITHUB_SHA
- shell: cmd
run: call "%GITHUB_WORKSPACE%\tests\windows\create-update-fixture.cmd"
- shell: cmd
run: call "%GITHUB_WORKSPACE%\update.cmd"
- shell: pwsh
run: ./tests/windows/assert-state.ps1 -RepoRoot $env:GITHUB_WORKSPACE -UpdateMarker $env:UPDATE_MARKER

windows-allsigned:
runs-on: windows-2025
timeout-minutes: 50
env:
DOTFILES_NONINTERACTIVE: "1"
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false
- shell: pwsh
run: ./tests/windows/prepare-ci.ps1
- shell: pwsh
run: ./tests/windows/enable-allsigned.ps1
- shell: cmd
run: pwsh.exe -NoProfile -File "%RUNNER_TEMP%\allsigned-bridge-smoke.ps1" -Value bridge-ok
- name: Run bootstrap under AllSigned
shell: cmd
run: |
mkdir "%RUNNER_TEMP%\dotfiles-run" 2>nul
pushd "%RUNNER_TEMP%\dotfiles-run"
call "%GITHUB_WORKSPACE%\bootstrap.cmd"
set "E=%ERRORLEVEL%"
popd
exit /b %E%
- shell: cmd
run: call "%GITHUB_WORKSPACE%\scripts\windows\invoke-ps-script.cmd" "%GITHUB_WORKSPACE%\tests\windows\assert-allsigned.ps1" -RepoRoot "%GITHUB_WORKSPACE%" -ThumbprintFile "%RUNNER_TEMP%\dotfiles-cert-thumbprint.txt"
- shell: cmd
run: call "%GITHUB_WORKSPACE%\tests\windows\create-update-fixture.cmd"
- shell: cmd
run: call "%GITHUB_WORKSPACE%\update.cmd"
- shell: cmd
run: call "%GITHUB_WORKSPACE%\scripts\windows\invoke-ps-script.cmd" "%GITHUB_WORKSPACE%\tests\windows\assert-allsigned.ps1" -RepoRoot "%GITHUB_WORKSPACE%" -ThumbprintFile "%RUNNER_TEMP%\dotfiles-cert-thumbprint.txt" -UpdateMarker "%UPDATE_MARKER%"
12 changes: 6 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.vscode

# Auto-generated files
config/zsh/.zcompcache/*
config/zsh/.zcompdump*
config/zsh/.zhistory
config/zsh/*/*.zwc
config/zsh/.zsh_sessions/*
home/dot_config/zsh/.zcompcache/*
home/dot_config/zsh/.zcompdump*
home/dot_config/zsh/.zhistory
home/dot_config/zsh/*/*.zwc
home/dot_config/zsh/.zsh_sessions/*

fonts/
fonts/
4 changes: 0 additions & 4 deletions .gitmodules

This file was deleted.

61 changes: 34 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,56 @@
# Dotfiles

Welcome to my dotfiles! This repository contains configurations and scripts to quickly set up a development environment on Windows and Linux.
This repository uses [chezmoi](https://www.chezmoi.io/) to deploy regular dotfiles on Windows and Linux. Repository support files stay outside the `home/` source state.

## Quick Installation
## Quick installation

### 🖥️ Windows
### Windows

To set up your environment on Windows, run the following command in PowerShell:
Run this from a normal `cmd.exe` prompt:

```powershell
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/jsilverdev/dotfiles/main/lets-go.ps1" -OutFile ".\lets-go.ps1"; Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned; .\lets-go.ps1
```cmd
curl.exe -fsSLo "%TEMP%\dotfiles-bootstrap.cmd" https://raw.githubusercontent.com/jsilverdev/dotfiles/main/bootstrap.cmd && call "%TEMP%\dotfiles-bootstrap.cmd"
```

To update installed applications and PowerShell modules:
The Windows bootstrap requires WinGet. If App Installer exists but WinGet is not registered for the current user, it attempts current-user App Installer registration. If corporate policy disables WinGet, it stops with an error. Bootstrap installs only Git, PowerShell 7, and chezmoi when they are missing; the platform installer owns the remaining application catalog.

```powershell
.\install.ps1 -Update # or -u
```
Baseline CLI packages are declared in `scripts/windows/managed-apps.csv` and are installed with WinGet in user scope. An interactive run also installs workstation applications, fonts, Windows Terminal customization, and offers optional applications. `DOTFILES_NONINTERACTIVE=1` installs the complete baseline but skips those interactive/workstation customizations.

The bootstrap does not require administrator rights or Developer Mode. It invokes PowerShell 7 with `-NoProfile`; an effective `AllSigned` policy is supported automatically. Each machine reuses or creates its own current-user Code Signing certificate and trusts its public certificate locally. No private key, PFX, or KeePass dependency is used.

### 🐧 Linux
### Linux

To set up your environment on Linux, use this command:
On Debian or Arch Linux, run:

```bash
bash <(curl -s https://raw.githubusercontent.com/jsilverdev/dotfiles/main/lets-go.sh)
bash <(curl -fsSL https://raw.githubusercontent.com/jsilverdev/dotfiles/main/bootstrap.sh)
```

To refresh existing packages, pass `--update` (or `-u`):
The bootstrap installs only the prerequisites required to obtain/apply the repository, installs chezmoi in `~/.local/bin` when needed, and then runs the package installer. Linux package catalogs are declared under `scripts/linux/`. Non-interactive mode still installs and validates the complete baseline; it only skips shell changes, WSL system configuration, and optional-package prompts. Arch continues to install and manage `yay`.

```bash
./install.sh --update
## Updates

For dotfiles-only updates, use:

```text
chezmoi update
```

## Requirements
For dotfiles plus installer-managed package/application/module updates, use `update.cmd` on Windows or `./update.sh` on Linux. Those wrappers run `chezmoi update` first and then rerun the platform installer in update mode. Starship and managed PowerShell modules participate in update mode as well.

## State details

- `home/.chezmoiroot` is represented by the repository-level `.chezmoiroot`, pointing to `home`.
- Windows-only `.wslconfig` and Linux-only Zsh/Sheldon state are filtered by `home/.chezmoiignore`.
- `~/.gitconfig.local`, `~/.codex/config.toml`, and `~/.codex/rules/default.rules` use chezmoi create-only semantics and are not overwritten after creation.
- Codex guidance and skills are managed normally; repository documentation is kept outside `~/.codex`.
- PowerShell source files are unsigned templates. The post-apply hook deploys copies and signs only the runtime files when `AllSigned` is effective, so Authenticode signatures never dirty chezmoi source state.
- Managed PowerShell modules are declared in `scripts/windows/managed-modules.txt`. Under `AllSigned`, managed PowerShell files are re-signed with the locally trusted dotfiles certificate unless they already carry a valid signature from that same certificate. This deliberately normalizes the publisher used by the non-interactive AllSigned path.

### 🖥️ Windows
- PowerShell
- [Dev Mode](https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) enabled
## CI and testing

### 🐧 Linux
- Debian / Arch Linux
- curl
The `Validate dotfiles` workflow exercises Debian, Arch Linux, Windows with its normal execution policy, and Windows with a simulated current-user `AllSigned` policy. GitHub Actions only orchestrates the scenarios; reusable fixture and assertion logic lives under `tests/`.

## Acknowledgments
Integration jobs bootstrap from a temporary local bare Git remote containing the exact commit under test. They run the real non-interactive baseline, validate installed CLI tools, exercise create-only Codex files and update wrappers, check idempotent chezmoi apply, and verify clean source/checkout state. Static validation includes ShellCheck, PowerShell parsing, manifest checks, chezmoi template evaluation, bridge-payload synchronization, and pinned `actionlint` validation of the workflow.

This dotfiles repository is inspired by:
- [Lissy93's dotfiles](https://github.com/Lissy93/dotfiles)
- [KEVINNITRO DOTFILES](https://github.com/KevinNitroG/dotfiles).
The Windows AllSigned job validates current-user certificate creation and reuse, Authenticode signing, the CMD execution bridge, PowerShell profile startup, and managed module loading. When PowerShell 7 requires signed scripts, the bridge uses inbox Windows PowerShell only for Authenticode signing and executes the resulting signed script with PowerShell 7 under the effective policy. The hosted runner is an administrator with UAC disabled, so CI trusts the test certificate through `LocalMachine\Root` plus `CurrentUser\TrustedPublisher`; runtime helpers also accept `CurrentUser\Root` for the real non-admin path. Corporate GPO/MDM/AppLocker/WDAC policy, enterprise App Installer policy, and a true non-admin corporate Windows 11 token still require validation on a managed machine.
File renamed without changes.
File renamed without changes.
114 changes: 114 additions & 0 deletions bootstrap.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
@echo off
setlocal EnableExtensions EnableDelayedExpansion

if defined DOTFILES_REPO (
set "REPO_URL=%DOTFILES_REPO%"
) else (
set "REPO_URL=https://github.com/jsilverdev/dotfiles.git"
)
where winget.exe >nul 2>&1
if errorlevel 1 (
echo WinGet is not registered for this user. Attempting App Installer registration...
"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
if errorlevel 1 (
echo App Installer registration failed. WinGet may be disabled by corporate policy. 1>&2
goto bootstrap_failed
)
)
where winget.exe >nul 2>&1
if errorlevel 1 (
echo WinGet is unavailable after App Installer registration. Check corporate policy or App Installer registration. 1>&2
goto bootstrap_failed
)
call :ensure_package Git.Git git
if errorlevel 1 goto bootstrap_failed
call :ensure_package Microsoft.PowerShell pwsh
if errorlevel 1 goto bootstrap_failed
call :ensure_package twpayne.chezmoi chezmoi
if errorlevel 1 goto bootstrap_failed
call :refresh_path
where git.exe >nul 2>&1
if errorlevel 1 (
echo Git is still unavailable after installation. 1>&2
goto bootstrap_failed
)
where pwsh.exe >nul 2>&1
if errorlevel 1 (
echo PowerShell 7 is still unavailable after installation. 1>&2
goto bootstrap_failed
)
where chezmoi.exe >nul 2>&1
if errorlevel 1 (
echo chezmoi is still unavailable after installation. 1>&2
goto bootstrap_failed
)
call :initialize_chezmoi
if errorlevel 1 (
echo chezmoi initialization/update failed. 1>&2
goto bootstrap_failed
)
call :resolve_repo_root
if not defined REPO_ROOT (
echo Unable to resolve the chezmoi working tree. 1>&2
goto bootstrap_failed
)
if not exist "%REPO_ROOT%\scripts\windows\invoke-ps-script.cmd" (
echo Resolved chezmoi working tree does not contain the dotfiles scripts: "%REPO_ROOT%" 1>&2
goto bootstrap_failed
)
if /I "%DOTFILES_NONINTERACTIVE%"=="1" (
call "%REPO_ROOT%\scripts\windows\invoke-ps-script.cmd" "%REPO_ROOT%\install.ps1" -NonInteractive -RepoRoot "%REPO_ROOT%"
) else (
call "%REPO_ROOT%\scripts\windows\invoke-ps-script.cmd" "%REPO_ROOT%\install.ps1" -RepoRoot "%REPO_ROOT%"
)
if errorlevel 1 goto bootstrap_failed
exit /b 0

:bootstrap_failed
exit /b 1

:ensure_package
set "PACKAGE_ID=%~1"
set "PACKAGE_COMMAND=%~2"
where "%PACKAGE_COMMAND%.exe" >nul 2>&1
if not errorlevel 1 exit /b 0
echo Installing %PACKAGE_ID% for the current user...
winget.exe install --id "%PACKAGE_ID%" --exact --source winget --scope user --silent --disable-interactivity --accept-source-agreements --accept-package-agreements
if errorlevel 1 (
echo Unable to install %PACKAGE_ID% without administrator rights. No machine-scope or portable fallback will be attempted. 1>&2
exit /b 1
)
exit /b 0

:refresh_path
set "PATH=%PATH%;%LOCALAPPDATA%\Microsoft\WinGet\Links;%LOCALAPPDATA%\Programs\Microsoft.PowerShell;%LOCALAPPDATA%\Programs\mise;%LOCALAPPDATA%\Programs\chezmoi"
for /f "tokens=2,*" %%A in ('reg query HKCU\Environment /v Path 2^>nul ^| findstr /i "Path"') do set "PATH=!PATH!;%%B"
exit /b 0

:resolve_repo_root
set "REPO_ROOT="
if exist "%CD%\.chezmoiroot" if exist "%CD%\install.ps1" (set "REPO_ROOT=%CD%"& exit /b 0)
for /f "delims=" %%R in ('chezmoi.exe execute-template "{{ .chezmoi.workingTree }}" 2^>nul') do set "REPO_ROOT=%%R"
if defined REPO_ROOT if exist "%REPO_ROOT%\install.ps1" exit /b 0
for /f "delims=" %%R in ('chezmoi.exe source-path 2^>nul') do set "SOURCE_ROOT=%%R"
if defined SOURCE_ROOT if exist "%SOURCE_ROOT%\install.ps1" (set "REPO_ROOT=%SOURCE_ROOT%"& exit /b 0)
if defined SOURCE_ROOT for %%P in ("%SOURCE_ROOT%\..") do if exist "%%~fP\install.ps1" (set "REPO_ROOT=%%~fP"& exit /b 0)
exit /b 1

:initialize_chezmoi
if exist "%CD%\.chezmoiroot" (
chezmoi.exe --source "%CD%" apply
exit /b %ERRORLEVEL%
)
set "SOURCE_ROOT="
for /f "delims=" %%R in ('chezmoi.exe source-path 2^>nul') do set "SOURCE_ROOT=%%R"
if defined SOURCE_ROOT if exist "%SOURCE_ROOT%\.chezmoiroot" goto existing_chezmoi
if defined SOURCE_ROOT for %%P in ("%SOURCE_ROOT%\..") do if exist "%%~fP\.chezmoiroot" goto existing_chezmoi
chezmoi.exe init "%REPO_URL%"
if errorlevel 1 exit /b %ERRORLEVEL%
chezmoi.exe apply
exit /b %ERRORLEVEL%

:existing_chezmoi
chezmoi.exe update
exit /b %ERRORLEVEL%
Loading