Compare commits

...

3 Commits

Author SHA1 Message Date
fa-sharp
6429112893 ci: permissions 2026-02-20 00:21:12 -05:00
fa-sharp
c0828867bd ci: add automated PR for dep upgrades 2026-02-20 00:10:02 -05:00
fa-sharp
4159d0d7ff Update dependency-check.yml 2026-02-19 23:42:15 -05:00
6 changed files with 190 additions and 4 deletions

82
.ci/merge_versions.py Normal file
View File

@@ -0,0 +1,82 @@
import re
import sys
def parse_toml_deps(content):
"""Extract dependency versions from TOML content."""
deps = {}
in_deps = False
for line in content.split("\n"):
if line.strip() == "[dependencies]":
in_deps = True
continue
if in_deps and line.strip().startswith("["):
break
if in_deps and "=" in line and not line.strip().startswith("#"):
# Parse: package = "version" or package = { version = "version", ... }
match = re.match(r'^\s*(\S+)\s*=\s*["{].*version\s*=\s*"([^"]+)"', line)
if match:
deps[match.group(1)] = match.group(2)
else:
match = re.match(r'^\s*(\S+)\s*=\s*"([^"]+)"', line)
if match:
deps[match.group(1)] = match.group(2)
return deps
def update_template_versions(template_content, new_versions):
"""Update versions in template while preserving Liquid syntax."""
lines = template_content.split("\n")
result = []
for line in lines:
updated_line = line
# Skip Liquid control flow lines
if re.match(r"^\s*{%", line):
result.append(line)
continue
# Check if this line has a dependency with version
for dep_name, new_version in new_versions.items():
# Match: package = "version"
pattern1 = rf'^(\s*{re.escape(dep_name)}\s*=\s*")([^"]+)(".*)'
match = re.match(pattern1, updated_line)
if match:
updated_line = f"{match.group(1)}{new_version}{match.group(3)}"
break
# Match: package = { version = "version", ... }
pattern2 = rf'^(\s*{re.escape(dep_name)}\s*=\s*{{[^}}]*version\s*=\s*")([^"]+)(".*)'
match = re.match(pattern2, updated_line)
if match:
updated_line = f"{match.group(1)}{new_version}{match.group(3)}"
break
result.append(updated_line)
return "\n".join(result)
if __name__ == "__main__":
# Read files
with open(sys.argv[1], "r") as f:
upgraded_content = f.read()
with open(sys.argv[2], "r") as f:
template_content = f.read()
# Extract new versions from upgraded Cargo.toml
new_versions = parse_toml_deps(upgraded_content)
print(f"Found {len(new_versions)} dependencies:")
for dep, version in sorted(new_versions.items()):
print(f" {dep} -> {version}")
# Update template while preserving Liquid syntax
updated_template = update_template_versions(template_content, new_versions)
# Write updated template
with open(sys.argv[2], "w") as f:
f.write(updated_template)
print("\n✅ Template updated successfully!")

9
.env.liquid Normal file
View File

@@ -0,0 +1,9 @@
# API Configuration
{{env_prefix}}_API_KEY=your-secret-api-key-here
# Server Configuration
{{env_prefix}}_HOST=127.0.0.1
{{env_prefix}}_PORT={{default_port}}
# Logging
{{env_prefix}}_LOG_LEVEL={{default_log_level}}

View File

@@ -1,3 +1,5 @@
.ci/
.github/
target/
Cargo.lock
.env

View File

@@ -16,6 +16,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
@@ -48,9 +50,29 @@ jobs:
# run: cargo test --verbose
# working-directory: dep-check-test
- name: Upgrade dependencies
- name: Upgrade dependencies and capture changes
id: upgrade
run: |
cargo upgrade --incompatible
# Run cargo upgrade and capture output
UPGRADE_OUTPUT=$(cargo upgrade --incompatible 2>&1)
echo "$UPGRADE_OUTPUT"
echo "$UPGRADE_OUTPUT" > ../upgrade-output.txt
# Check if any dependencies were actually upgraded
if echo "$UPGRADE_OUTPUT" | grep -E "name\s+old req\s+compatible\s+latest\s+new req" > /dev/null; then
# Check if any version actually changed (old req != new req)
if echo "$UPGRADE_OUTPUT" | tail -n +3 | awk '{if ($2 != $5 && $2 != "" && $5 != "") exit 0} END {exit 1}'; then
echo "has_updates=true" >> $GITHUB_OUTPUT
echo "✅ Updates detected"
else
echo "has_updates=false" >> $GITHUB_OUTPUT
echo " No updates available"
fi
else
echo "has_updates=false" >> $GITHUB_OUTPUT
echo " No updates available"
fi
cat Cargo.toml
working-directory: dep-check-test
@@ -66,6 +88,20 @@ jobs:
# run: cargo test --verbose
# working-directory: dep-check-test
- name: Update template Cargo.toml if upgrades succeeded
if: steps.upgrade.outputs.has_updates == 'true'
run: |
echo "📝 Updating template with new dependency versions..."
# Run the merge script from .ci directory
python3 .ci/merge_versions.py dep-check-test/Cargo.toml Cargo.toml.liquid
# Show what changed
echo ""
echo "Changes to template:"
git diff Cargo.toml.liquid
working-directory: ${{ github.workspace }}/axum-template
- name: Create issue on failure
if: failure()
run: |
@@ -120,6 +156,58 @@ jobs:
# run: cargo test --verbose
# working-directory: dep-check-no-aide
- name: Prepare PR body with upgrade summary
if: steps.upgrade.outputs.has_updates == 'true'
run: |
UPGRADE_SUMMARY=$(cat upgrade-output.txt | grep -A 100 "name.*old req.*compatible.*latest.*new req" | head -n 20)
cat > pr-body.txt << 'EOF'
This PR contains automated dependency upgrades that have been tested with `cargo check` and `cargo build`
## Changes
```
EOF
echo "$UPGRADE_SUMMARY" >> pr-body.txt
cat >> pr-body.txt << 'EOF'
```
## Testing
✅ Generated test project with aide
✅ Generated test project without aide
✅ All builds passed
✅ All checks passed
## Workflow Run
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
---
*This PR was automatically created by the dependency check workflow.*
EOF
cat pr-body.txt
working-directory: ${{ github.workspace }}
- name: Create Pull Request with dependency updates
if: steps.upgrade.outputs.has_updates == 'true'
uses: infinilabs/gitea-pr@v0
permissions:
contents: write
with:
url: ${{ github.server_url }}
token: ${{ secrets.GITHUB_TOKEN }}
path: ${{ github.workspace }}/axum-template
commit-message: "chore: upgrade dependencies"
committer: "Dependency Bot <bot@github.actions>"
author: "Dependency Bot <bot@github.actions>"
base: ${{ github.ref_name }}
branch: deps/auto-upgrade-${{ github.run_number }}
title: "⬆️ Automated Dependency Upgrade"
body-path: ${{ github.workspace }}/pr-body.txt
pr-label: "dependencies"
- name: Summary
if: success()
run: |
@@ -129,4 +217,8 @@ jobs:
echo " - With aide: dep-check-test"
echo " - Without aide: dep-check-no-aide"
echo ""
echo "All upgraded dependencies are compatible."
if [ "${{ steps.upgrade.outputs.has_updates }}" = "true" ]; then
echo "📦 Updates found - PR created automatically"
else
echo " No dependency updates available"
fi

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/target
.env*
!.env.example
!.env.liquid

View File

@@ -58,7 +58,7 @@ APP_PORT=8080
APP_LOG_LEVEL=info
```
In development, you can use a `.env` file (copy from `.env.example`).
In development, you can use the `.env` file.
## Project Structure