Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
6e48353
build: openwrt 25.12.1
Tbaile Mar 25, 2026
34bc1c6
chore: updated build container
Tbaile Mar 25, 2026
71297d3
build(ppp): upstream patched the package
Tbaile Mar 25, 2026
e0dfdf2
build: openwrt 25.12.2
Tbaile Apr 15, 2026
2f2b966
build(netifyd): updated binaries
Tbaile Apr 15, 2026
142f196
fix: updated syntax due to python update
Tbaile Apr 16, 2026
68e7811
chore: updated checkmk version
Tbaile May 5, 2026
6bcf128
build: added suffix support
Tbaile Apr 29, 2026
63104fc
updated variable generation
Tbaile Apr 29, 2026
e0e9dee
chore: updated python semver package
Tbaile May 5, 2026
fd69a11
fixed release path
Tbaile May 5, 2026
4bda23a
feat: added victoria-metrics package
Tbaile Apr 30, 2026
f336a02
feat: added victoria-logs
Tbaile Apr 30, 2026
d22b8c0
feat: added telegraf package
Tbaile Apr 30, 2026
430d085
fix: updated spdx
Tbaile Apr 30, 2026
79a6015
feat: compiling packages
Tbaile Apr 30, 2026
92192bf
fix: accidentally overwrote telegraf config
Tbaile Apr 30, 2026
c500942
fix: addressed deprecation warnings and removed not useful comments
Tbaile Apr 30, 2026
e6fb87b
fix: adjusted config for sensors and ethtool
Tbaile Apr 30, 2026
3366ac0
chore: updated monitoring tools
Tbaile May 5, 2026
8e9257c
chore: downgraded version to keep compatibility with go
Tbaile May 5, 2026
cccc7a9
chore: added skill to update packages
Tbaile May 5, 2026
fff7f6d
ci: fixed versioning for image build
Tbaile May 5, 2026
0fd5c77
chore: removed ipcalc fork
Tbaile May 12, 2026
61c03b9
chore: removed jinja2 fork
Tbaile May 12, 2026
3bb8293
build: updated signing method for APKs (#1659)
Tbaile May 12, 2026
910e983
build: compiling avahi mdns (#1657)
Tbaile May 12, 2026
a536baa
build: updated debian version and openwrt version
Tbaile May 12, 2026
1c7aea4
chore: move back history to persistend dir
gsanchietti May 14, 2026
296a3fe
build: fixed issue where env variables were not honoured
Tbaile May 15, 2026
137c102
build: bumped to 24.12.4
Tbaile May 15, 2026
57711f8
feat(victoria): add vmalert alerting
gsanchietti Apr 22, 2026
4192cfd
feat(api): replace ns.netdata with ns.telegraf
gsanchietti Apr 23, 2026
2aef7b8
feat(telegraf): add missing plugins
gsanchietti Apr 30, 2026
8fee8e5
refactor(ns-plug): remove netdata
gsanchietti May 5, 2026
64f8a28
feat(telegraf): using uci conf for ping config, added migration path …
Tbaile May 7, 2026
0e3b1aa
chore(ns-ui): version bump
Tbaile May 7, 2026
437e44d
fix(telegraf): moving pruning of netdata config to telegraf migration
Tbaile May 7, 2026
1cc3835
fix(ns-api): using uci config for pings
Tbaile May 13, 2026
8e2e4a6
fix(ns-plug): added service triggers for alert-proxy
Tbaile May 13, 2026
f77d74b
feat(victoria-metrics): added storage configuration
Tbaile May 15, 2026
80de1ec
chore(ns-ui): version bump
Tbaile May 15, 2026
b26a723
chore(skill): improve OpenWrt package update
Tbaile May 11, 2026
d03d4fd
chore: updated adblock to 4.5.5-3
Tbaile May 11, 2026
64f1c26
fix(adblock): reload nft rules
gsanchietti May 15, 2026
66f4eee
fix(adblock): stage dns list changes
gsanchietti May 15, 2026
927f9c8
fix(ipsec): add restart dpd_action
gsanchietti May 15, 2026
8b69a3e
chore(ui): bump to dev commit
gsanchietti May 15, 2026
82bb798
refactor: using http sink for flows ingestion (#1678)
Tbaile May 18, 2026
78fbbd1
chore: build pyton3 from commits instead of versions for ease of test…
Tbaile May 18, 2026
c1058bc
build: removing routing and video from feeds
Tbaile May 18, 2026
b2004ec
refactor: migrate package management from opkg to apk
m-dilorenzi May 8, 2026
d5fe247
fix: update installation commands from opkg to apk across documentation
m-dilorenzi May 12, 2026
42b158e
fix: update copyright year to 2026 across multiple files
m-dilorenzi May 13, 2026
1c272db
chore(doc): update command for custom repos
gsanchietti May 14, 2026
2bcb041
fix(ns-restore-extra-packages): improve resilience and output reliabi…
gsanchietti May 14, 2026
a312fe2
fix(distfeed-setup): ensure version is stripped of suffix when unset
m-dilorenzi May 15, 2026
1353814
fix(update-packages): fix packages update flow
m-dilorenzi May 18, 2026
a279c5b
fix(update-packages): disabled custom feeds packages update with auto…
m-dilorenzi May 18, 2026
8ee53ab
fix(ns-plug): revert 40_ns-plug_automatic_updates
m-dilorenzi May 18, 2026
459d060
fix(snort.uc): fix installation command for apk
m-dilorenzi May 18, 2026
a2b24fd
build: added back snmpd (#1683)
Tbaile May 19, 2026
91a55f8
chore: updated snort (#1682)
Tbaile May 19, 2026
03b27b7
chore(ns-ui): hash bump
Tbaile May 20, 2026
61c6285
fix(openvpn-status): manage real_address format after OpenVPN version…
m-dilorenzi May 21, 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
60 changes: 60 additions & 0 deletions .agents/skills/openwrt-package-update/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: openwrt-package-update
description: >
Use when updating any forked OpenWrt package in a NethSecurity workspace from
the upstream openwrt/packages feed. Covers the full update cycle: version bump,
merging upstream file changes, updating dependent ns-api handlers and migration
scripts, UCI overlay defaults, and correlated documentation. Triggers on updating
a package by name (adblock, mwan3, banip, rsyslog, snort3, keepalived,
python-jinja2, python-semver, and similar forks), syncing with upstream, or any
request to align a local package fork with openwrt/packages — even if upstream
is not mentioned explicitly.
compatibility: Requires git and curl. Works in a NethSecurity workspace with build.conf.defaults present.
metadata:
domain: nethsecurity-packages
type: package-update
allowed-tools: Bash(git:*) Bash(curl:*) Bash(diff:*) Bash(tar:*) Bash(grep:*) Bash(sed:*) Bash(awk:*) Read Write
---

## What I do

Update a forked upstream OpenWrt package from the openwrt/packages feed. Auto-discovers the package path, compares the current version against the upstream target, extracts snapshots for comparison, applies upstream changes, propagates impact to ns-api handlers and migration scripts, and updates correlated documentation.

## Quick start

1. **Setup**: `bash scripts/setup-package.sh <package-name>` — auto-discovers upstream path, finds version commits, extracts old/new snapshots into `assets/<name>_old/` and `assets/<name>_new/`
2. **Compare**: `bash scripts/diff-package.sh <package-name>` — shows what changed upstream
3. **Merge**: Read both snapshots, apply upstream changes to local files in `packages/<package-name>/`; update PKG_VERSION and PKG_RELEASE in the Makefile
4. **Cross-package**: Grep for any changed config keys or function names in ns-api, migration scripts, and files/ overlay; update as needed
5. **Documentation**: Update `docs/` and `packages/ns-api/README.md` if user-facing behavior changed
6. **Verify**: Run `ruff check` on any changed Python files; build the package inside the container

For per-step detail on any of the above, read [references/WORKFLOW.md](references/WORKFLOW.md).

## How it works

The skill uses three helper scripts:

- **get-target-commit.sh** — reads `build.conf.defaults` for OWRT_VERSION, fetches `feeds.conf.default` from that tag, extracts the openwrt/packages commit hash
- **setup-package.sh** — auto-discovers package upstream path, uses git pickaxe to find the commit matching current PKG_VERSION then PKG_RELEASE, clones/fetches openwrt/packages bare repo into `assets/.openwrt-packages-repo/` (persistent cache), extracts both versions into named snapshots
- **diff-package.sh** — convenience wrapper: `diff -rN assets/<name>_old/ assets/<name>_new/`

## Snapshot structure

Each snapshot has the exact upstream package files at root level:
```
assets/adblock_old/
├── Makefile
├── files/
│ ├── adblock.sh
│ ├── adblock.init
│ ├── adblock.conf
│ └── ...
```

## Edge cases

- **mwan3**: Deep fork — apply upstream changes conservatively, one by one
- **snort3**: Has local patches — verify patches still apply after update
- **Version not found**: If script fails, local version is very old; check `assets/.openwrt-packages-repo/` git history
- **Empty diff**: Versions match; only update PKG_VERSION/PKG_RELEASE if tracking newer release
1 change: 1 addition & 0 deletions .agents/skills/openwrt-package-update/assets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
88 changes: 88 additions & 0 deletions .agents/skills/openwrt-package-update/references/WORKFLOW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Detailed Workflow: Updating Upstream Packages

## 1. Identify the package

Confirm the package exists and is in scope. Read `packages/<package-name>/Makefile` to understand the current version:
- Note PKG_VERSION and PKG_RELEASE
- Check if `packages/<package-name>/patches/` exists (indicates local patches)
- Scan `files/` directory to understand what configuration files and scripts are included

## 2. Setup snapshots

Run the setup script:
```bash
bash scripts/setup-package.sh <package-name>
```

This script will:
- Auto-discover the upstream path in openwrt/packages (e.g., `net/adblock`)
- Use git pickaxe to find the commit that introduced the current PKG_VERSION
- Then find the commit that set the current PKG_RELEASE
- Extract both versions into `assets/<package-name>_old/` and `assets/<package-name>_new/`
- Output summary with commit hashes and paths

## 3. Compare and classify

Examine both snapshots using your file reading tools. Run:
```bash
bash scripts/diff-package.sh <package-name>
```

Classify each change:
- **Makefile**: version bumps, new dependencies, build flags
- **files/*.sh** / **files/*.init**: behavioral changes to shell scripts
- **files/*.conf**: UCI configuration schema changes (new/removed/renamed options)
- **files/*.sources**, **files/*.categories**, data files: content-only updates
- **New files** added / **files removed**

## 4. Apply upstream changes

For each changed file:
- If the local copy is identical to old version or has no NethSecurity-specific changes → take upstream as-is
- If the local copy has customizations → merge carefully:
- Use the diff tool to understand what changed upstream
- Manually integrate the upstream changes into the local file
- Preserve any NethSecurity-specific logic or configuration

Always:
- Update PKG_VERSION and PKG_RELEASE in `packages/<package-name>/Makefile`
- If `packages/<package-name>/patches/` exists, re-verify each patch still applies cleanly with the new version
- Test build: `make package/feeds/nethsecurity/<name>/compile V=sc` inside the build container

## 5. Cross-package impact detection

For each changed UCI option name, function name, or config key in the diff:
- Grep the workspace for references:
```bash
grep -r "<changed-key>" packages/ files/ docs/ --include="*.py" --include="*.sh" --include="*.json" --include="*.conf" --include="*.md"
```
- Grep `packages/ns-migration/` for migration scripts that reference old option names
- Grep `packages/ns-api/` for API scripts that read/write this package's configuration
- Present findings to user before making changes

## 6. Apply cross-package fixes (after user confirmation)

Update affected files:
- **ns-api scripts**: if UCI schema changed, update handlers in `packages/ns-api/files/ns.<name>`
- **Migration scripts**: if old config options are removed, add migration logic to `packages/ns-migration/files/`
- **files/ overlay defaults**: if default values changed, update `files/etc/uci-defaults/` or `files/etc/config/`
- **Documentation**: update `docs/` if user-facing behavior changed

## Edge cases

**mwan3**: This is a deep fork with significant local modifications. Apply upstream changes one by one, preferring manual review for any behavioral change. Verify the result against firewall rules and failover behavior.

**snort3, openvpn-easy-rsa**: These packages have local patches (see `packages/<name>/patches/`). After updating upstream files, re-run `quilt refresh` or regenerate patches. If patches no longer apply cleanly, update them to match the new upstream.

**Empty diff**: If upstream and local versions are the same, only update PKG_VERSION/PKG_RELEASE in the Makefile if tracking a newer release. Otherwise, the package is up-to-date.

**Version not found**: If the script cannot find the current PKG_VERSION in upstream history, it means the local version is very old or from a different source. Check git history in the bare repo (`assets/.openwrt-packages-repo/`) to understand the version trajectory.

## Helpful commands

Inside the skill directory:
- `bash scripts/get-target-commit.sh` — print the target packages feed commit hash from feeds.conf.default
- `bash scripts/setup-package.sh <name>` — extract old/new snapshots
- `bash scripts/diff-package.sh <name>` — show recursive diff
- `find assets/<name>_old/ -type f` — list all files in old snapshot
- `cat assets/<name>_old/Makefile | grep PKG_` — check old version details
38 changes: 38 additions & 0 deletions .agents/skills/openwrt-package-update/scripts/diff-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash
#
# Diff old and new package snapshots
#
# Usage: diff-package.sh <package-name>
#
# Outputs a recursive diff between assets/<name>_old/ and assets/<name>_new/
#

set -euo pipefail

PACKAGE_NAME="${1:-}"

if [[ -z "$PACKAGE_NAME" ]]; then
echo "Usage: diff-package.sh <package-name>" >&2
exit 1
fi

# Find skill root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ASSETS_DIR="$SKILL_ROOT/assets"

OLD_DIR="$ASSETS_DIR/${PACKAGE_NAME}_old"
NEW_DIR="$ASSETS_DIR/${PACKAGE_NAME}_new"

if [[ ! -d "$OLD_DIR" ]]; then
echo "Error: $OLD_DIR not found. Run setup-package.sh first." >&2
exit 1
fi

if [[ ! -d "$NEW_DIR" ]]; then
echo "Error: $NEW_DIR not found. Run setup-package.sh first." >&2
exit 1
fi

# Run recursive diff, showing added/removed/modified files
diff -rN "$OLD_DIR" "$NEW_DIR" || true
44 changes: 44 additions & 0 deletions .agents/skills/openwrt-package-update/scripts/get-target-commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash
#
# Get the target OpenWrt packages feed commit hash from feeds.conf.default
# at the version specified in build.conf.defaults
#
# Outputs the commit hash to stdout, or exits with error if fetch/parse fails.
#

set -euo pipefail

# Find workspace root
WORKSPACE_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && git rev-parse --show-toplevel 2>/dev/null || echo ".")

# Read OWRT_VERSION from build.conf.defaults
if [[ ! -f "$WORKSPACE_ROOT/build.conf.defaults" ]]; then
echo "Error: build.conf.defaults not found at $WORKSPACE_ROOT" >&2
exit 1
fi

OWRT_VERSION=$(grep '^OWRT_VERSION=' "$WORKSPACE_ROOT/build.conf.defaults" | cut -d'=' -f2 | tr -d ' ')

if [[ -z "$OWRT_VERSION" ]]; then
echo "Error: OWRT_VERSION not found or empty in build.conf.defaults" >&2
exit 1
fi

# Fetch feeds.conf.default from OpenWrt at the specified tag
FEEDS_URL="https://raw.githubusercontent.com/openwrt/openwrt/$OWRT_VERSION/feeds.conf.default"

FEEDS_CONTENT=$(curl -fsSL "$FEEDS_URL" 2>/dev/null || {
echo "Error: Failed to fetch $FEEDS_URL" >&2
exit 1
})

# Parse the packages line to extract the commit hash (after the ^)
# Expected format: src-git packages https://git.openwrt.org/feed/packages.git^<hash>
PACKAGES_COMMIT=$(echo "$FEEDS_CONTENT" | grep '^src-git packages' | sed 's/.*\^//g' | head -1)

if [[ -z "$PACKAGES_COMMIT" ]]; then
echo "Error: Could not parse packages commit hash from feeds.conf.default" >&2
exit 1
fi

echo "$PACKAGES_COMMIT"
162 changes: 162 additions & 0 deletions .agents/skills/openwrt-package-update/scripts/setup-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/bin/bash
#
# Setup old and new package snapshots for comparison
#
# Usage: setup-package.sh <package-name>
#
# Outputs:
# - Creates assets/<name>_old/ with the current pinned upstream version
# - Creates assets/<name>_new/ with the target upstream version (from feeds.conf.default)
# - Prints to stdout: package name, CURRENT_COMMIT, TARGET_COMMIT, upstream path
#

set -euo pipefail

PACKAGE_NAME="${1:-}"

if [[ -z "$PACKAGE_NAME" ]]; then
echo "Usage: setup-package.sh <package-name>" >&2
exit 1
fi

# Find workspace root (convert to absolute path)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT=$(cd "$SCRIPT_DIR/../../../.." && git rev-parse --show-toplevel 2>/dev/null || pwd)
SKILL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ASSETS_DIR="$SKILL_ROOT/assets"

# Ensure assets dir exists
mkdir -p "$ASSETS_DIR"

# Read current package version from local Makefile
LOCAL_MAKEFILE="$WORKSPACE_ROOT/packages/$PACKAGE_NAME/Makefile"
if [[ ! -f "$LOCAL_MAKEFILE" ]]; then
echo "Error: $LOCAL_MAKEFILE not found" >&2
exit 1
fi

PKG_VERSION=$(grep '^PKG_VERSION:=' "$LOCAL_MAKEFILE" | cut -d'=' -f2 | tr -d ' ')
PKG_RELEASE=$(grep '^PKG_RELEASE:=' "$LOCAL_MAKEFILE" | cut -d'=' -f2 | tr -d ' ')

if [[ -z "$PKG_VERSION" ]]; then
echo "Error: PKG_VERSION not found in $LOCAL_MAKEFILE" >&2
exit 1
fi

echo "Package: $PACKAGE_NAME (version $PKG_VERSION-$PKG_RELEASE)" >&2

# Get target commit from feeds.conf.default
TARGET_COMMIT=$("$SKILL_ROOT/scripts/get-target-commit.sh")
echo "Target commit: $TARGET_COMMIT" >&2

# Clone/fetch openwrt/packages bare repo
BARE_REPO="$ASSETS_DIR/.openwrt-packages-repo"

if [[ ! -d "$BARE_REPO" ]]; then
echo "Cloning openwrt/packages (bare repo)..." >&2
git clone --bare --filter=blob:none https://github.com/openwrt/packages.git "$BARE_REPO" 2>/dev/null || {
echo "Error: Failed to clone openwrt/packages" >&2
exit 1
}
else
echo "Fetching openwrt/packages..." >&2
cd "$BARE_REPO"
git fetch origin 2>/dev/null || {
echo "Error: Failed to fetch openwrt/packages" >&2
exit 1
}
cd - > /dev/null
fi

# Auto-discover the upstream path by searching for <package-name>/Makefile
# Look in the target commit first to find the exact path
echo "Discovering upstream package path..." >&2
UPSTREAM_PATH=$(cd "$BARE_REPO" && git ls-tree -r --name-only "$TARGET_COMMIT" | grep -E "^[^/]+/$PACKAGE_NAME/Makefile$" | sed 's|/Makefile$||' | head -1)

if [[ -z "$UPSTREAM_PATH" ]]; then
echo "Error: Could not find $PACKAGE_NAME in upstream openwrt/packages at $TARGET_COMMIT" >&2
exit 1
fi

echo "Upstream path: $UPSTREAM_PATH" >&2

# Find the commit that introduced the current version
# Step 1: Find when PKG_VERSION was introduced using pickaxe
# Step 2: Find when PKG_RELEASE was set using pickaxe
echo "Finding commit that matches local version ($PKG_VERSION-$PKG_RELEASE)..." >&2

CURRENT_COMMIT=""

# Step 1: Find commits that introduced PKG_VERSION
echo " Step 1: Finding commits with PKG_VERSION:=$PKG_VERSION..." >&2
version_commits=$(cd "$BARE_REPO" && git log -S "PKG_VERSION:=$PKG_VERSION" --all --format="%H" -- "$UPSTREAM_PATH/Makefile" 2>/dev/null)

if [[ -z "$version_commits" ]]; then
echo "Error: Could not find PKG_VERSION:=$PKG_VERSION in git history" >&2
exit 1
fi

# Get the oldest commit where PKG_VERSION was introduced (last in the list when searching backwards)
version_commit=$(echo "$version_commits" | tail -1)
echo " PKG_VERSION introduced at: $version_commit" >&2

# Step 2: From that commit forward, find when PKG_RELEASE was set
# We search commits from version_commit onwards for PKG_RELEASE change
echo " Step 2: Finding commits with PKG_RELEASE:=$PKG_RELEASE after version introduction..." >&2
release_commits=$(cd "$BARE_REPO" && git log -S "PKG_RELEASE:=$PKG_RELEASE" --all --format="%H" -- "$UPSTREAM_PATH/Makefile" 2>/dev/null)

if [[ -n "$release_commits" ]]; then
# Find the first commit in release_commits that is an ancestor of or after version_commit
# Also verify both PKG_VERSION and PKG_RELEASE are present
while IFS= read -r commit; do
makefile_content=$(cd "$BARE_REPO" && git show "$commit:$UPSTREAM_PATH/Makefile" 2>/dev/null || echo "")

if echo "$makefile_content" | grep -q "^PKG_VERSION:=$PKG_VERSION" && \
echo "$makefile_content" | grep -q "^PKG_RELEASE:=$PKG_RELEASE"; then
CURRENT_COMMIT="$commit"
break
fi
done <<< "$release_commits"
fi

if [[ -z "$CURRENT_COMMIT" ]]; then
echo "Error: Could not find a commit matching $PKG_VERSION-$PKG_RELEASE in upstream history" >&2
echo "Available version range (last 20 commits):" >&2
cd "$BARE_REPO" && git log --all --oneline -20 -- "$UPSTREAM_PATH/Makefile" >&2
exit 1
fi

echo "Current commit: $CURRENT_COMMIT" >&2

# Extract the old version (current commit)
OLD_DIR="$ASSETS_DIR/${PACKAGE_NAME}_old"
rm -rf "$OLD_DIR"
mkdir -p "$OLD_DIR"

echo "Extracting old version to $OLD_DIR..." >&2
strip_level=$(echo "$UPSTREAM_PATH" | awk -F/ '{print NF}')
cd "$BARE_REPO" && git archive "$CURRENT_COMMIT" "$UPSTREAM_PATH/" | tar -x --strip-components=$strip_level -C "$OLD_DIR" 2>/dev/null || {
echo "Error: Failed to extract old version" >&2
exit 1
}

# Extract the new version (target commit)
NEW_DIR="$ASSETS_DIR/${PACKAGE_NAME}_new"
rm -rf "$NEW_DIR"
mkdir -p "$NEW_DIR"

echo "Extracting new version to $NEW_DIR..." >&2
cd "$BARE_REPO" && git archive "$TARGET_COMMIT" "$UPSTREAM_PATH/" | tar -x --strip-components=$strip_level -C "$NEW_DIR" 2>/dev/null || {
echo "Error: Failed to extract new version" >&2
exit 1
}

# Output summary to stdout
echo ""
echo "===== SETUP COMPLETE ====="
echo "Package: $PACKAGE_NAME"
echo "Current upstream commit: $CURRENT_COMMIT"
echo "Target upstream commit: $TARGET_COMMIT"
echo "Upstream path: $UPSTREAM_PATH"
echo "Old version snapshot: $OLD_DIR"
echo "New version snapshot: $NEW_DIR"
Loading
Loading