Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: CI

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x]

steps:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm test -- --coverage --watchAll=false

- name: Upload coverage reports
if: ${{ secrets.CODECOV_TOKEN != '' }}
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true

build:
needs: test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build
path: build/
54 changes: 54 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Code Quality

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run ESLint
run: npx eslint src/**/*.{ts,tsx} --max-warnings=0

- name: Type check
run: npx tsc --noEmit

security:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run npm audit
run: npm audit --production

- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
228 changes: 228 additions & 0 deletions update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
#!/bin/bash

set -e

if [ "$#" -ne 2 ]; then
echo "Usage: $0 <child_project_path> <last_version_tag>"
exit 1
fi

CHILD_PATH="$1"
LAST_TAG="$2"
ROOT_PATH="$(pwd)"

if [ ! -d "$CHILD_PATH" ]; then
echo "Child project path does not exist: $CHILD_PATH"
exit 1
fi

# 1. Get changed files
CHANGED=$(git diff --name-status "$LAST_TAG" HEAD)

# 2. Prepare lists
ADDED_MODIFIED=()
DELETED=()
RENAMED=()

while IFS= read -r line; do
STATUS=$(echo "$line" | awk '{print $1}')
if [[ "$STATUS" == "R"* ]]; then
# For renamed files, the format is "R<similarity> old_file new_file"
OLD_FILE=$(echo "$line" | awk '{print $2}')
NEW_FILE=$(echo "$line" | awk '{print $3}')
if [[ "$OLD_FILE" == UPGRADE*.md || "$OLD_FILE" == "update.sh" ]]; then
continue
fi
RENAMED+=("$OLD_FILE|$NEW_FILE")
elif [[ "$STATUS" == "A" || "$STATUS" == "M" ]]; then
FILE=$(echo "$line" | awk '{print $2}')
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
ADDED_MODIFIED+=("$FILE")
elif [[ "$STATUS" == "D" ]]; then
FILE=$(echo "$line" | awk '{print $2}')
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
DELETED+=("$FILE")
fi
done <<< "$CHANGED"

# 3. Handle renamed files first
for RENAME in "${RENAMED[@]}"; do
OLD_FILE=$(echo "$RENAME" | cut -d'|' -f1)
NEW_FILE=$(echo "$RENAME" | cut -d'|' -f2)

OLD_PATH="$CHILD_PATH/$OLD_FILE"
NEW_PATH="$CHILD_PATH/$NEW_FILE"

# Always copy the new file from the main repo to the new location in the child repo
mkdir -p "$(dirname "$NEW_PATH")"
cp "$NEW_FILE" "$NEW_PATH"
echo "Copied $NEW_FILE to $NEW_PATH in child repository (rename from $OLD_FILE)"

# If the old file exists in the child repo, delete it
if [ -f "$OLD_PATH" ]; then
rm "$OLD_PATH"
echo "Deleted old file $OLD_PATH in child repository (renamed to $NEW_FILE)"
fi
done

# 4. Copy new/modified files
SAFE_FILES=()
for FILE in "${ADDED_MODIFIED[@]}"; do
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
DEST="$CHILD_PATH/$FILE"
# Check if the file is new in the child repo
if [ ! -f "$DEST" ]; then
SAFE_FILES+=("$FILE")
fi
mkdir -p "$(dirname "$DEST")"
cp "$FILE" "$DEST"
echo "Copied $FILE to $DEST"
done

# 5. Delete removed files
for FILE in "${DELETED[@]}"; do
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
TARGET="$CHILD_PATH/$FILE"
if [ -f "$TARGET" ]; then
rm "$TARGET"
echo "Deleted $TARGET"
fi
done

# 6. Compare diffs and report
# Get the latest tag for the 'to' version
TO_TAG=$(git describe --tags --abbrev=0)
REPORT_NAME="update_report_${LAST_TAG}_to_${TO_TAG}.txt"
REPORT="$CHILD_PATH/$REPORT_NAME"
> "$REPORT"

# Compare added/modified files
for FILE in "${ADDED_MODIFIED[@]}"; do
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
# Generate unified diff in main repo
git diff "$LAST_TAG" -- "$FILE" | grep -v '^index' | sed 's/[[:space:]]*$//' > /tmp/main_diff
# Generate unified diff in child repo
pushd "$CHILD_PATH" > /dev/null
git diff -- "$FILE" | grep -v '^index' | sed 's/[[:space:]]*$//' > /tmp/child_diff
popd > /dev/null
# Compare the diffs byte-for-byte
if ! diff -q /tmp/main_diff /tmp/child_diff > /dev/null; then
echo "$FILE" >> "$REPORT"
fi
rm -f /tmp/main_diff /tmp/child_diff
done

# Compare renamed files
for RENAME in "${RENAMED[@]}"; do
OLD_FILE=$(echo "$RENAME" | cut -d'|' -f1)
NEW_FILE=$(echo "$RENAME" | cut -d'|' -f2)

if [[ "$OLD_FILE" == UPGRADE*.md || "$OLD_FILE" == "update.sh" ]]; then
continue
fi

# Generate unified diff in main repo for the rename
git diff "$LAST_TAG" -- "$NEW_FILE" | grep -v '^index' | sed 's/[[:space:]]*$//' > /tmp/main_diff
# Generate unified diff in child repo for the new file
pushd "$CHILD_PATH" > /dev/null
git diff -- "$NEW_FILE" | grep -v '^index' | sed 's/[[:space:]]*$//' > /tmp/child_diff
popd > /dev/null
# Compare the diffs byte-for-byte
if ! diff -q /tmp/main_diff /tmp/child_diff > /dev/null; then
echo "$NEW_FILE (renamed from $OLD_FILE)" >> "$REPORT"
fi
rm -f /tmp/main_diff /tmp/child_diff
done

# Compare deleted files
for FILE in "${DELETED[@]}"; do
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
# Generate unified diff in main repo for deleted file
git diff "$LAST_TAG" -- "$FILE" | grep -v '^index' | sed 's/[[:space:]]*$//' > /tmp/main_diff
# Generate unified diff in child repo for deleted file
pushd "$CHILD_PATH" > /dev/null
git diff -- "$FILE" | grep -v '^index' | sed 's/[[:space:]]*$//' > /tmp/child_diff
popd > /dev/null
# Compare the diffs byte-for-byte
if ! diff -q /tmp/main_diff /tmp/child_diff > /dev/null; then
echo "$FILE" >> "$REPORT"
fi
rm -f /tmp/main_diff /tmp/child_diff
done

if [ -s "$REPORT" ]; then
echo "Update report created: $REPORT"
cat "$REPORT"
else
echo "All files updated and verified. No mismatches found."
rm "$REPORT"
fi

# Update README.md in the child project
README="$CHILD_PATH/README.md"
VERSION_LINE="This is based on the core of Athenia version number $TO_TAG"
if [ -f "$README" ]; then
if grep -q "This is based on the core of Athenia version number" "$README"; then
sed -i '' "s|This is based on the core of Athenia version number.*|$VERSION_LINE|" "$README"
else
echo "$VERSION_LINE" >> "$README"
fi
else
echo "$VERSION_LINE" > "$README"
fi

# Git add all updated files not in the report
pushd "$CHILD_PATH" > /dev/null
REPORTED=()
if [ -f "$REPORT_NAME" ]; then
while IFS= read -r line; do
REPORTED+=("$line")
done < "$REPORT_NAME"
fi

should_add() {
local file="$1"
for reported in "${REPORTED[@]}"; do
if [[ "$file" == "$reported" ]]; then
return 1
fi
done
return 0
}

for FILE in "${ADDED_MODIFIED[@]}"; do
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
should_add "$FILE" && git add "$FILE"
done

for FILE in "${DELETED[@]}"; do
if [[ "$FILE" == UPGRADE*.md || "$FILE" == "update.sh" ]]; then
continue
fi
if [ ! -f "$FILE" ]; then
should_add "$FILE" && git rm --cached "$FILE" 2>/dev/null || true
fi
done
popd > /dev/null

# Stage safe files for commit
echo "Staging safe files for commit..."
cd "$CHILD_PATH"
for FILE in "${SAFE_FILES[@]}"; do
git add "$FILE"
done
git add README.md
Loading