Skip to content

Commit 26b1df3

Browse files
Merge pull request #13 from ahmed-n-abdeltwab/feature/make-modular
feat(ci): implement direct download links for model releases
2 parents 2f5f0f9 + c6995da commit 26b1df3

File tree

1 file changed

+48
-56
lines changed

1 file changed

+48
-56
lines changed
+48-56
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1-
name: Model Training and Release
1+
name: Model Training and Release Pipeline
22

33
on:
44
push:
55
branches: [ main ]
6-
tags: [ 'v*.*.*' ] # Trigger on version tags
6+
tags: [ 'v*.*.*' ]
77
workflow_dispatch:
88

99
env:
1010
DOCKER_IMAGE: spyware-detector
1111
RELEASE_DIR: release
12+
RELEASE_FILENAME: model_release.tar.gz # Consistent filename for direct downloads
1213

1314
jobs:
1415
train-and-release:
1516
runs-on: ubuntu-latest
1617
permissions:
17-
contents: write # Required for creating releases
18+
contents: write
1819
packages: write
1920
actions: read
2021

2122
steps:
23+
# --- Setup Phase ---
2224
- name: Checkout repository
2325
uses: actions/checkout@v4
2426
with:
25-
fetch-depth: 0 # Needed for tag detection
27+
fetch-depth: 0 # Required for tag operations
2628

2729
- name: Set up Python 3.9
2830
uses: actions/setup-python@v4
@@ -33,16 +35,16 @@ jobs:
3335
run: |
3436
python -m pip install --upgrade pip
3537
pip install -r requirements.txt
38+
sudo apt-get install -y jq
3639
37-
- name: Install jq
38-
run: sudo apt-get install -y jq
39-
40+
# --- Build Phase ---
4041
- name: Build Docker image
4142
run: |
4243
docker build -t $DOCKER_IMAGE .
4344
docker images
4445
45-
- name: Prepare release directory
46+
# --- Training Phase ---
47+
- name: Prepare workspace
4648
run: |
4749
mkdir -p ./$RELEASE_DIR/latest
4850
chmod -R 777 ./$RELEASE_DIR
@@ -57,92 +59,82 @@ jobs:
5759
-u 1001 \
5860
$DOCKER_IMAGE
5961
60-
- name: Verify artifacts
62+
# --- Verification Phase ---
63+
- name: Validate artifacts
6164
run: |
62-
echo "Generated artifacts:"
65+
echo "Artifact Verification:"
6366
ls -lR ./$RELEASE_DIR/latest
64-
65-
REQUIRED_FILES=(
67+
68+
declare -a REQUIRED_FILES=(
6669
"model.pkl"
6770
"metadata.json"
6871
"metrics.json"
6972
"feature_structure.json"
7073
)
71-
72-
missing_files=0
74+
7375
for file in "${REQUIRED_FILES[@]}"; do
7476
if [ ! -f "./$RELEASE_DIR/latest/$file" ]; then
75-
echo "Error: Required file $file not found!"
76-
missing_files=$((missing_files+1))
77+
echo "::error::Missing required file: $file"
78+
exit 1
7779
fi
7880
done
79-
80-
if [ $missing_files -gt 0 ]; then
81-
echo "Error: Missing $missing_files required files!"
82-
docker logs $(docker ps -lq) || true
83-
exit 1
84-
fi
8581
82+
# --- Packaging Phase ---
8683
- name: Package release assets
8784
run: |
88-
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
89-
RELEASE_NAME="model_$TIMESTAMP"
90-
91-
# Create archive with all artifacts
92-
tar -czvf ./$RELEASE_DIR/$RELEASE_NAME.tar.gz -C ./$RELEASE_DIR/latest .
93-
94-
# Create version file
95-
MODEL_VERSION=$(jq -r '.timestamp + "-" + .model_type' ./$RELEASE_DIR/latest/metadata.json)
96-
echo $MODEL_VERSION > ./$RELEASE_DIR/version.txt
85+
# Create standardized filename for direct downloads
86+
tar -czvf ./$RELEASE_DIR/$RELEASE_FILENAME -C ./$RELEASE_DIR/latest .
9787
98-
echo "Release assets prepared:"
99-
ls -l ./$RELEASE_DIR/*.tar.gz
88+
# Generate version info
89+
jq '. + {download_url: "https://github.com/${{ github.repository }}/releases/latest/download/$RELEASE_FILENAME"}' \
90+
./$RELEASE_DIR/latest/metadata.json > ./$RELEASE_DIR/latest/release_info.json
10091
101-
- name: Auto-tag release (on main branch)
92+
echo "Packaged assets:"
93+
ls -l ./$RELEASE_DIR/
94+
95+
# --- Release Phase ---
96+
- name: Auto-generate version tag
10297
if: github.ref == 'refs/heads/main'
10398
id: autotag
10499
run: |
105-
# Get version from metadata
106-
VERSION=$(jq -r '.timestamp' ./$RELEASE_DIR/latest/metadata.json | cut -c1-10 | tr -d '-')
100+
VERSION=$(date +%Y%m%d)
107101
TAG_NAME="v1.0.$VERSION"
108-
109-
# Create lightweight tag
110102
git tag $TAG_NAME
111103
git push origin $TAG_NAME
112-
113104
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
105+
echo "Generated tag: $TAG_NAME"
114106
115107
- name: Create GitHub Release
116108
uses: softprops/action-gh-release@v1
117109
with:
118110
tag_name: ${{ github.ref_name || steps.autotag.outputs.tag_name }}
119111
name: "Model Release ${{ github.ref_name || steps.autotag.outputs.tag_name }}"
120112
body: |
121-
## Model Details
122-
- **Type**: $(jq -r '.model_type' ./$RELEASE_DIR/latest/metadata.json)
123-
- **Training Date**: $(jq -r '.timestamp' ./$RELEASE_DIR/latest/metadata.json)
124-
125-
## Performance Metrics
113+
## 📦 Model Package
114+
**Direct Download:**
115+
[Download $RELEASE_FILENAME](https://github.com/${{ github.repository }}/releases/latest/download/$RELEASE_FILENAME)
116+
117+
### 🚀 Model Details
118+
```json
119+
$(cat ./$RELEASE_DIR/latest/metadata.json | jq -c '{model_type, timestamp, hyperparameters}')
120+
```
121+
122+
### 📊 Performance Metrics
126123
```json
127124
$(cat ./$RELEASE_DIR/latest/metrics.json)
128125
```
129-
130-
## Version Info
131-
$(cat ./$RELEASE_DIR/version.txt)
132126
files: |
133-
${{ env.RELEASE_DIR }}/*.tar.gz
134-
${{ env.RELEASE_DIR }}/latest/metadata.json
135-
${{ env.RELEASE_DIR }}/latest/metrics.json
127+
${{ env.RELEASE_DIR }}/${{ env.RELEASE_FILENAME }}
128+
${{ env.RELEASE_DIR }}/latest/release_info.json
136129
draft: false
137130
prerelease: false
138-
env:
139-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
140131

132+
# --- Fallback Artifact ---
141133
- name: Upload workflow artifact
134+
if: ${{ !success() }}
142135
uses: actions/upload-artifact@v4
143136
with:
144-
name: model-release
137+
name: model-artifacts
145138
path: |
146-
${{ env.RELEASE_DIR }}/*.tar.gz
147-
${{ env.RELEASE_DIR }}/version.txt
148-
if-no-files-found: error
139+
${{ env.RELEASE_DIR }}/*
140+
retention-days: 7

0 commit comments

Comments
 (0)