Skip to content

Merge pull request #12 from ahmed-n-abdeltwab/feature/make-modular #15

Merge pull request #12 from ahmed-n-abdeltwab/feature/make-modular

Merge pull request #12 from ahmed-n-abdeltwab/feature/make-modular #15

name: Model Training and Release
on:
push:
branches: [ main ]
tags: [ 'v*.*.*' ] # Trigger on version tags
workflow_dispatch:
env:
DOCKER_IMAGE: spyware-detector
RELEASE_DIR: release
jobs:
train-and-release:
runs-on: ubuntu-latest
permissions:
contents: write # Required for creating releases
packages: write
actions: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed for tag detection
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Install jq
run: sudo apt-get install -y jq
- name: Build Docker image
run: |
docker build -t $DOCKER_IMAGE .
docker images
- name: Prepare release directory
run: |
mkdir -p ./$RELEASE_DIR/latest
chmod -R 777 ./$RELEASE_DIR
- name: Run training pipeline
run: |
docker run --rm \
-v $(pwd)/data:/app/data \
-v $(pwd)/models:/app/models \
-v $(pwd)/$RELEASE_DIR:/app/release \
-e PYTHONPATH=/app \
-u 1001 \
$DOCKER_IMAGE
- name: Verify artifacts
run: |
echo "Generated artifacts:"
ls -lR ./$RELEASE_DIR/latest
REQUIRED_FILES=(
"model.pkl"
"metadata.json"
"metrics.json"
"feature_structure.json"
)
missing_files=0
for file in "${REQUIRED_FILES[@]}"; do
if [ ! -f "./$RELEASE_DIR/latest/$file" ]; then
echo "Error: Required file $file not found!"
missing_files=$((missing_files+1))
fi
done
if [ $missing_files -gt 0 ]; then
echo "Error: Missing $missing_files required files!"
docker logs $(docker ps -lq) || true
exit 1
fi
- name: Package release assets
run: |
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
RELEASE_NAME="model_$TIMESTAMP"
# Create archive with all artifacts
tar -czvf ./$RELEASE_DIR/$RELEASE_NAME.tar.gz -C ./$RELEASE_DIR/latest .
# Create version file
MODEL_VERSION=$(jq -r '.timestamp + "-" + .model_type' ./$RELEASE_DIR/latest/metadata.json)
echo $MODEL_VERSION > ./$RELEASE_DIR/version.txt
echo "Release assets prepared:"
ls -l ./$RELEASE_DIR/*.tar.gz
- name: Auto-tag release (on main branch)
if: github.ref == 'refs/heads/main'
id: autotag
run: |
# Get version from metadata
VERSION=$(jq -r '.timestamp' ./$RELEASE_DIR/latest/metadata.json | cut -c1-10 | tr -d '-')
TAG_NAME="v1.0.$VERSION"
# Create lightweight tag
git tag $TAG_NAME
git push origin $TAG_NAME
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ github.ref_name || steps.autotag.outputs.tag_name }}
name: "Model Release ${{ github.ref_name || steps.autotag.outputs.tag_name }}"
body: |
## Model Details
- **Type**: $(jq -r '.model_type' ./$RELEASE_DIR/latest/metadata.json)
- **Training Date**: $(jq -r '.timestamp' ./$RELEASE_DIR/latest/metadata.json)
## Performance Metrics
```json
$(cat ./$RELEASE_DIR/latest/metrics.json)
```
## Version Info
$(cat ./$RELEASE_DIR/version.txt)
files: |
${{ env.RELEASE_DIR }}/*.tar.gz
${{ env.RELEASE_DIR }}/latest/metadata.json
${{ env.RELEASE_DIR }}/latest/metrics.json
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload workflow artifact
uses: actions/upload-artifact@v4
with:
name: model-release
path: |
${{ env.RELEASE_DIR }}/*.tar.gz
${{ env.RELEASE_DIR }}/version.txt
if-no-files-found: error