Skip to content

Commit abf518e

Browse files
chore: add script for release
1 parent 88b37af commit abf518e

File tree

4 files changed

+257
-32
lines changed

4 files changed

+257
-32
lines changed

.github/workflows/release-agent.yml

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -160,24 +160,11 @@ jobs:
160160
echo "Publishing netdriver-agent to PyPI..."
161161
poetry publish -C projects/agent --skip-existing
162162
163-
- name: Get wheel file path
164-
id: wheel
165-
run: |
166-
WHEEL_FILE=$(ls projects/agent/dist/*.whl)
167-
WHEEL_NAME=$(basename $WHEEL_FILE)
168-
echo "path=$WHEEL_FILE" >> $GITHUB_OUTPUT
169-
echo "name=$WHEEL_NAME" >> $GITHUB_OUTPUT
170-
echo "Found wheel file: $WHEEL_NAME"
171-
172163
- name: Upload wheel to release
173-
uses: actions/upload-release-asset@v1
174-
env:
175-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
164+
uses: softprops/action-gh-release@v1
176165
with:
177-
upload_url: ${{ needs.create-release.outputs.upload_url }}
178-
asset_path: ${{ steps.wheel.outputs.path }}
179-
asset_name: ${{ steps.wheel.outputs.name }}
180-
asset_content_type: application/zip
166+
tag_name: agent-${{ needs.create-release.outputs.version }}
167+
files: projects/agent/dist/*.whl
181168

182169
build-docker-image:
183170
name: Build and Push Agent Docker Image

.github/workflows/release-simunet.yml

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -160,24 +160,11 @@ jobs:
160160
echo "Publishing netdriver-simunet to PyPI..."
161161
poetry publish -C projects/simunet --skip-existing
162162
163-
- name: Get wheel file path
164-
id: wheel
165-
run: |
166-
WHEEL_FILE=$(ls projects/simunet/dist/*.whl)
167-
WHEEL_NAME=$(basename $WHEEL_FILE)
168-
echo "path=$WHEEL_FILE" >> $GITHUB_OUTPUT
169-
echo "name=$WHEEL_NAME" >> $GITHUB_OUTPUT
170-
echo "Found wheel file: $WHEEL_NAME"
171-
172163
- name: Upload wheel to release
173-
uses: actions/upload-release-asset@v1
174-
env:
175-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
164+
uses: softprops/action-gh-release@v1
176165
with:
177-
upload_url: ${{ needs.create-release.outputs.upload_url }}
178-
asset_path: ${{ steps.wheel.outputs.path }}
179-
asset_name: ${{ steps.wheel.outputs.name }}
180-
asset_content_type: application/zip
166+
tag_name: simunet-${{ needs.create-release.outputs.version }}
167+
files: projects/simunet/dist/*.whl
181168

182169
build-docker-image:
183170
name: Build and Push Simunet Docker Image

scripts/README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Release Scripts
2+
3+
This directory contains scripts to help with the release process.
4+
5+
## release.sh
6+
7+
A convenient script to create and push release tags.
8+
9+
### Usage
10+
11+
```bash
12+
./scripts/release.sh <project> <version>
13+
```
14+
15+
**Parameters:**
16+
17+
- `project`: The project to release (`agent` or `simunet`)
18+
- `version`: Version number in format `X.X.X` (e.g., `0.3.5`)
19+
20+
### Examples
21+
22+
**Release netdriver-agent version 0.3.5:**
23+
24+
```bash
25+
./scripts/release.sh agent 0.3.5
26+
```
27+
28+
**Release netdriver-simunet version 0.4.0:**
29+
30+
```bash
31+
./scripts/release.sh simunet 0.4.0
32+
```
33+
34+
### What it does
35+
36+
1. Validates input parameters
37+
2. Checks prerequisites (git repository, poetry installation)
38+
3. Verifies working directory is clean
39+
4. Verifies the tag doesn't already exist
40+
5. Updates version in `projects/<project>/pyproject.toml` using `poetry version`
41+
6. Commits the version change
42+
7. Creates an annotated git tag (e.g., `agent-0.3.5`)
43+
8. Pushes the commit and tag to remote
44+
9. Triggers the GitHub Actions release workflow
45+
46+
### Release Workflow
47+
48+
Once the tag is pushed, the GitHub Actions workflow will automatically:
49+
50+
1. **Create GitHub Release** with release notes
51+
2. **Run Tests** (pylint + pytest)
52+
3. **Build and Publish to PyPI**
53+
- Build wheel package
54+
- Publish to PyPI
55+
- Upload wheel to GitHub release
56+
4. **Build and Push Docker Image**
57+
- Build multi-platform image (linux/amd64, linux/arm64)
58+
- Push to GitHub Container Registry (ghcr.io)
59+
- Tag with version and `latest`
60+
5. **Verify Publication**
61+
- Check PyPI package availability
62+
- Generate summary
63+
64+
### Troubleshooting
65+
66+
**Tag already exists:**
67+
68+
```bash
69+
# Delete local tag
70+
git tag -d agent-0.3.5
71+
72+
# Delete remote tag
73+
git push origin :refs/tags/agent-0.3.5
74+
75+
# Try again
76+
./scripts/release.sh agent 0.3.5
77+
```
78+
79+
**Workflow failed:**
80+
81+
- Check GitHub Actions: <https://github.com/OpenSecFlow/netdriver/actions>
82+
- Review workflow logs for specific errors
83+
- Fix issues and delete/recreate the tag if needed
84+
85+
### Prerequisites
86+
87+
- **Poetry** installed and configured
88+
- **Git** configured and authenticated
89+
- Push permissions to the repository
90+
- **Clean working directory** (no uncommitted changes)

scripts/release.sh

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Colors for output
6+
RED='\033[0;31m'
7+
GREEN='\033[0;32m'
8+
YELLOW='\033[1;33m'
9+
BLUE='\033[0;34m'
10+
NC='\033[0m' # No Color
11+
12+
# Function to print colored messages
13+
print_info() {
14+
echo -e "${BLUE}${NC}$1"
15+
}
16+
17+
print_success() {
18+
echo -e "${GREEN}${NC} $1"
19+
}
20+
21+
print_warning() {
22+
echo -e "${YELLOW}${NC} $1"
23+
}
24+
25+
print_error() {
26+
echo -e "${RED}${NC} $1"
27+
}
28+
29+
# Function to show usage
30+
usage() {
31+
cat << EOF
32+
Usage: $0 <project> <version>
33+
34+
Create a release for NetDriver projects.
35+
36+
Arguments:
37+
project Project to release: agent or simunet
38+
version Version number (e.g., 0.3.5)
39+
40+
Examples:
41+
$0 agent 0.3.5
42+
$0 simunet 0.4.0
43+
44+
This script will:
45+
1. Update version in pyproject.toml using poetry
46+
2. Commit version changes
47+
3. Create a git tag (agent-X.X.X or simunet-X.X.X)
48+
4. Push changes and tag to trigger the release workflow
49+
EOF
50+
exit 1
51+
}
52+
53+
# Check arguments
54+
if [ $# -ne 2 ]; then
55+
print_error "Invalid number of arguments"
56+
usage
57+
fi
58+
59+
PROJECT=$1
60+
VERSION=$2
61+
62+
# Validate project
63+
if [[ "$PROJECT" != "agent" && "$PROJECT" != "simunet" ]]; then
64+
print_error "Invalid project: $PROJECT"
65+
print_error "Project must be 'agent' or 'simunet'"
66+
exit 1
67+
fi
68+
69+
# Validate version format (X.X.X)
70+
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
71+
print_error "Invalid version format: $VERSION"
72+
print_error "Version must be in format X.X.X (e.g., 0.3.5)"
73+
exit 1
74+
fi
75+
76+
TAG_NAME="${PROJECT}-${VERSION}"
77+
78+
print_info "Release Configuration"
79+
echo " Project: $PROJECT"
80+
echo " Version: $VERSION"
81+
echo " Tag: $TAG_NAME"
82+
echo
83+
84+
# Check if we're in a git repository
85+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
86+
print_error "Not in a git repository"
87+
exit 1
88+
fi
89+
90+
# Check if poetry is installed
91+
if ! command -v poetry &> /dev/null; then
92+
print_error "Poetry is not installed"
93+
print_error "Install it from: https://python-poetry.org/docs/#installation"
94+
exit 1
95+
fi
96+
97+
# Check if working directory is clean
98+
if ! git diff-index --quiet HEAD --; then
99+
print_error "Working directory has uncommitted changes"
100+
print_error "Please commit or stash your changes before creating a release"
101+
exit 1
102+
fi
103+
104+
# Check if tag already exists
105+
if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
106+
print_error "Tag $TAG_NAME already exists"
107+
echo
108+
print_info "To delete the tag locally and remotely, run:"
109+
echo " git tag -d $TAG_NAME"
110+
echo " git push origin :refs/tags/$TAG_NAME"
111+
exit 1
112+
fi
113+
114+
# Get current branch
115+
CURRENT_BRANCH=$(git branch --show-current)
116+
print_info "Current branch: $CURRENT_BRANCH"
117+
118+
# Confirm release
119+
echo
120+
print_warning "This will update version, commit, create tag, and push to remote"
121+
read -p "Continue? (y/N) " -n 1 -r
122+
echo
123+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
124+
print_error "Aborted"
125+
exit 1
126+
fi
127+
128+
# Update version in pyproject.toml
129+
echo
130+
print_info "Updating version in projects/${PROJECT}/pyproject.toml to ${VERSION}..."
131+
poetry version "$VERSION" -C "projects/${PROJECT}"
132+
print_success "Version updated"
133+
134+
# Commit version changes
135+
print_info "Committing version changes..."
136+
git add "projects/${PROJECT}/pyproject.toml"
137+
git commit -m "chore: bump ${PROJECT} version to ${VERSION}"
138+
print_success "Version changes committed"
139+
140+
# Create tag
141+
print_info "Creating tag $TAG_NAME..."
142+
git tag -a "$TAG_NAME" -m "Release $PROJECT $VERSION"
143+
print_success "Tag created"
144+
145+
# Push changes and tag
146+
print_info "Pushing changes and tag to remote..."
147+
git push origin "$CURRENT_BRANCH"
148+
git push origin "$TAG_NAME"
149+
print_success "Changes and tag pushed"
150+
151+
echo
152+
print_success "Release initiated successfully!"
153+
echo
154+
print_info "Monitor the release workflow at:"
155+
echo " https://github.com/OpenSecFlow/netdriver/actions"
156+
echo
157+
print_info "Once the workflow completes, the release will be available at:"
158+
echo " https://github.com/OpenSecFlow/netdriver/releases/tag/$TAG_NAME"
159+
echo
160+
print_info "The package will be published to PyPI as:"
161+
echo " pip install netdriver-${PROJECT}==${VERSION}"

0 commit comments

Comments
 (0)