Skip to content

v1.1.0

v1.1.0 #13

Workflow file for this run

name: Full Release Pipeline
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 1.0.6)'
required: true
type: string
jobs:
release:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
packages: write
steps:
# ============================================
# 1. Checkout and Setup
# ============================================
- name: Checkout repository
uses: actions/checkout@v6
with:
ref: main
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Install AWS CLI
run: pip install awscli
- name: Configure AWS CLI for Yandex Cloud
env:
AWS_ACCESS_KEY_ID: ${{ secrets.YANDEX_STORAGE_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.YANDEX_STORAGE_SECRET_KEY }}
run: |
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set default.region ru-central1
# ============================================
# 2. Extract version from release tag
# ============================================
- name: Extract version from tag
id: version
run: |
# Get version from release event or workflow_dispatch input
if [ -n "${{ github.event.release.tag_name }}" ]; then
TAG="${{ github.event.release.tag_name }}"
VERSION="${TAG#v}"
else
VERSION="${{ github.event.inputs.version }}"
TAG="v${VERSION}"
fi
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "version_folder=v${VERSION}" >> $GITHUB_OUTPUT
echo "📦 Release tag: $TAG"
echo "📦 Version: $VERSION"
# ============================================
# 3. Update package.json and package-lock.json
# ============================================
- name: Update package.json version
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
echo "📝 Updating package.json to version $VERSION..."
npm version $VERSION --no-git-tag-version --allow-same-version
echo "✅ package.json updated"
grep '"version"' package.json | head -1
# ============================================
# 4. Update src/core.js version (source of truth)
# ============================================
# Note: prefetch.js and prefetch.esm.js are now generated by build.js
# which reads version from package.json and replaces __VERSION__ placeholder
- name: Update README.md version
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
echo "📝 Updating README.md to version $VERSION..."
# Update version in JavaScript API example: // "1.0.X"
sed -i "s|// \"[0-9]*\.[0-9]*\.[0-9]*\"|// \"${VERSION}\"|g" README.md
echo "✅ README.md updated"
grep -n "Prefetch.version" README.md | head -1
# ============================================
# 5. Build dist/prefetch.min.js + dist/prefetch.esm.min.js
# ============================================
- name: Build minified versions
run: |
echo "🔨 Building dist/prefetch.min.js + dist/prefetch.esm.min.js..."
npm run build
echo "✅ Build complete"
ls -la dist/
# ============================================
# 6. Calculate SRI Hash
# ============================================
- name: Calculate SRI integrity hash
id: sri
run: |
echo "🔐 Calculating SRI hash..."
# IIFE версия
SRI_HASH=$(openssl dgst -sha384 -binary dist/prefetch.min.js | openssl base64 -A)
FULL_SRI="sha384-${SRI_HASH}"
# ESM версия
ESM_SRI_HASH=$(openssl dgst -sha384 -binary dist/prefetch.esm.min.js | openssl base64 -A)
FULL_ESM_SRI="sha384-${ESM_SRI_HASH}"
echo "sri_hash=$FULL_SRI" >> $GITHUB_OUTPUT
echo "esm_sri_hash=$FULL_ESM_SRI" >> $GITHUB_OUTPUT
echo "🔐 IIFE SRI Hash: $FULL_SRI"
echo "🔐 ESM SRI Hash: $FULL_ESM_SRI"
# ============================================
# 7. Upload to CDN bucket
# ============================================
- name: Upload prefetch.min.js to CDN
env:
BUCKET: ${{ secrets.YANDEX_STORAGE_BUCKET_CDN }}
ENDPOINT: ${{ secrets.YANDEX_STORAGE_ENDPOINT }}
VERSION_FOLDER: ${{ steps.version.outputs.version_folder }}
VERSION: ${{ steps.version.outputs.version }}
SRI_HASH: ${{ steps.sri.outputs.sri_hash }}
run: |
echo "📤 Uploading to CDN: $BUCKET/$VERSION_FOLDER/prefetch.min.js"
aws s3 cp dist/prefetch.min.js \
s3://${BUCKET}/${VERSION_FOLDER}/prefetch.min.js \
--endpoint-url ${ENDPOINT} \
--content-type "application/javascript; charset=utf-8" \
--cache-control "public, max-age=31536000, immutable" \
--metadata "version=${VERSION},sri-hash=${SRI_HASH}"
echo "✅ Uploaded to: s3://${BUCKET}/${VERSION_FOLDER}/prefetch.min.js"
# ============================================
# 8. Update www/index.html
# ============================================
- name: Update index.html with new version and SRI
env:
VERSION: ${{ steps.version.outputs.version }}
VERSION_FOLDER: ${{ steps.version.outputs.version_folder }}
SRI_HASH: ${{ steps.sri.outputs.sri_hash }}
run: |
echo "📝 Updating www/index.html..."
# Replace all version paths: /v1.0.X/ -> /vNEW/
sed -i "s|/v[0-9]*\.[0-9]*\.[0-9]*/|/${VERSION_FOLDER}/|g" www/index.html
# Replace all SRI hashes (handles both plain HTML and syntax-highlighted code)
# Pattern 1: integrity="sha384-..."
sed -i "s|integrity=\"sha384-[^\"]*\"|integrity=\"${SRI_HASH}\"|g" www/index.html
# Pattern 2: "sha384-..." in code spans (for syntax highlighting)
sed -i "s|\"sha384-[^\"]*\"|\"${SRI_HASH}\"|g" www/index.html
# Replace "Версия X.X.X" text
sed -i "s|Версия [0-9]*\.[0-9]*\.[0-9]*|Версия ${VERSION}|g" www/index.html
# Replace version in code examples: // "X.X.X"
sed -i "s|// \"[0-9]*\.[0-9]*\.[0-9]*\"|// \"${VERSION}\"|g" www/index.html
echo "✅ www/index.html updated"
echo ""
echo "📄 Updated lines:"
grep -n "/${VERSION_FOLDER}/" www/index.html | head -5
grep -n "Версия ${VERSION}" www/index.html | head -2
# ============================================
# 9. Update www/sitemap.xml
# ============================================
- name: Update sitemap.xml with current date
run: |
echo "📝 Updating www/sitemap.xml..."
TODAY=$(date -u +"%Y-%m-%d")
sed -i "s|<lastmod>[0-9-]*</lastmod>|<lastmod>${TODAY}</lastmod>|g" www/sitemap.xml
echo "✅ www/sitemap.xml updated with date: $TODAY"
cat www/sitemap.xml
# ============================================
# 10. Minify index.html
# ============================================
- name: Minify index.html
run: |
echo "🔨 Minifying www/index.html..."
# Размер до минификации
BEFORE=$(stat -c%s www/index.html)
echo "📄 Before: $BEFORE bytes"
# Минификация HTML
npx --yes html-minifier-terser \
--collapse-whitespace \
--remove-comments \
--remove-redundant-attributes \
--remove-script-type-attributes \
--remove-style-link-type-attributes \
--minify-css true \
--minify-js true \
--input-dir www \
--output-dir www \
--file-ext html
# Размер после минификации
AFTER=$(stat -c%s www/index.html)
SAVED=$((BEFORE - AFTER))
PERCENT=$((SAVED * 100 / BEFORE))
echo "📄 After: $AFTER bytes"
echo "✅ Saved: $SAVED bytes ($PERCENT%)"
# ============================================
# 11. Upload www/ to MAIN bucket
# ============================================
- name: Upload www/ to MAIN bucket
env:
BUCKET: ${{ secrets.YANDEX_STORAGE_BUCKET_MAIN }}
ENDPOINT: ${{ secrets.YANDEX_STORAGE_ENDPOINT }}
run: |
echo "📤 Uploading www/ to MAIN bucket: $BUCKET"
aws s3 sync ./www/ s3://${BUCKET}/ \
--endpoint-url ${ENDPOINT} \
--delete \
--exclude ".git*" \
--exclude ".github*"
echo "✅ www/ uploaded to MAIN bucket"
- name: Verify MAIN bucket contents
env:
BUCKET: ${{ secrets.YANDEX_STORAGE_BUCKET_MAIN }}
ENDPOINT: ${{ secrets.YANDEX_STORAGE_ENDPOINT }}
run: |
echo "📁 Contents of MAIN bucket:"
aws s3 ls s3://${BUCKET}/ \
--endpoint-url ${ENDPOINT} \
--recursive \
--human-readable
# ============================================
# 12. Commit changes back to repository
# ============================================
- name: Commit version updates
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
# Check if there are changes
if git diff --quiet && git diff --cached --quiet; then
echo "ℹ️ No changes to commit"
else
# prefetch.js, prefetch.esm.js and dist/ are in .gitignore — use -f to force add
git add -f prefetch.js prefetch.esm.js dist/
git add package.json package-lock.json README.md www/index.html www/sitemap.xml
git commit -m "chore: release v${VERSION} - update version, SRI hash, sitemap [skip ci]"
git push origin main
echo "✅ Changes committed and pushed"
fi
# ============================================
# 13. Create release artifacts
# ============================================
- name: Create release artifacts
env:
SRI_HASH: ${{ steps.sri.outputs.sri_hash }}
ESM_SRI_HASH: ${{ steps.sri.outputs.esm_sri_hash }}
VERSION: ${{ steps.version.outputs.version }}
run: |
echo "📦 Creating release artifacts..."
# Create artifacts directory
mkdir -p artifacts
# Copy minified files
cp dist/prefetch.min.js artifacts/
cp dist/prefetch.esm.min.js artifacts/
cd artifacts
# IIFE version: MD5 + SRI + ZIP
md5sum prefetch.min.js > prefetch.min.js.md5
echo "${SRI_HASH}" > prefetch.min.js.sri
zip prefetch.min.js.zip prefetch.min.js prefetch.min.js.md5 prefetch.min.js.sri
# ESM version: MD5 + SRI + ZIP
md5sum prefetch.esm.min.js > prefetch.esm.min.js.md5
echo "${ESM_SRI_HASH}" > prefetch.esm.min.js.sri
zip prefetch.esm.min.js.zip prefetch.esm.min.js prefetch.esm.min.js.md5 prefetch.esm.min.js.sri
cd ..
echo "✅ Artifacts created:"
ls -la artifacts/
echo ""
echo "📄 IIFE MD5:"
cat artifacts/prefetch.min.js.md5
echo "📄 IIFE SRI:"
cat artifacts/prefetch.min.js.sri
echo ""
echo "📄 ESM MD5:"
cat artifacts/prefetch.esm.min.js.md5
echo "📄 ESM SRI:"
cat artifacts/prefetch.esm.min.js.sri
echo ""
echo "📦 IIFE ZIP contents:"
unzip -l artifacts/prefetch.min.js.zip
echo ""
echo "📦 ESM ZIP contents:"
unzip -l artifacts/prefetch.esm.min.js.zip
# ============================================
# 14. Upload artifacts to release
# ============================================
- name: Upload release assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "📤 Uploading assets to release..."
TAG="${{ steps.version.outputs.tag }}"
gh release upload "$TAG" \
artifacts/prefetch.min.js.zip \
artifacts/prefetch.esm.min.js.zip \
--clobber
echo "✅ Assets uploaded to release"
- name: Update release notes with SRI hash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SRI_HASH: ${{ steps.sri.outputs.sri_hash }}
run: |
echo "📝 Updating release notes..."
# Get current release body
TAG="${{ steps.version.outputs.tag }}"
CURRENT_BODY=$(gh release view "$TAG" --json body -q '.body')
# Create notes file with only SRI
{
echo ""
echo "---"
echo ""
echo "## Integrity (SRI) IIFE — prefetch.min.js"
echo ""
echo '```'
echo "${SRI_HASH}"
echo '```'
} > /tmp/release_notes.md
# Combine current body with new notes
echo "${CURRENT_BODY}" > /tmp/full_notes.md
cat /tmp/release_notes.md >> /tmp/full_notes.md
# Update release
gh release edit "$TAG" --notes-file /tmp/full_notes.md
echo "✅ Release notes updated with SRI hash"
# ============================================
# 15. Publish to npm
# ============================================
- name: Remove auth token for OIDC
run: |
# Remove authToken from .npmrc to allow OIDC authentication
sed -i '/_authToken/d' $NPM_CONFIG_USERCONFIG 2>/dev/null || true
- name: Publish to npm (OIDC Trusted Publishing)
run: npm publish --access public --provenance
continue-on-error: true # Don't fail if version already exists
# ============================================
# 16. Publish to GitHub Packages
# ============================================
- name: Setup for GitHub Packages
uses: actions/setup-node@v6
with:
node-version: '24'
registry-url: 'https://npm.pkg.github.com'
scope: '@prefetch-ru'
- name: Update package name for GitHub Packages
run: npm pkg set name="@prefetch-ru/prefetch"
- name: Publish to GitHub Packages
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
# ============================================
# Summary
# ============================================
- name: Release Summary
env:
VERSION: ${{ steps.version.outputs.version }}
VERSION_FOLDER: ${{ steps.version.outputs.version_folder }}
SRI_HASH: ${{ steps.sri.outputs.sri_hash }}
BUCKET_CDN: ${{ secrets.YANDEX_STORAGE_BUCKET_CDN }}
BUCKET_MAIN: ${{ secrets.YANDEX_STORAGE_BUCKET_MAIN }}
run: |
echo ""
echo "=========================================="
echo "🎉 Release v${VERSION} Complete!"
echo "=========================================="
echo ""
echo "📦 Version: ${VERSION}"
echo "🔐 SRI Hash: ${SRI_HASH}"
echo ""
echo "📁 CDN: s3://${BUCKET_CDN}/${VERSION_FOLDER}/prefetch.min.js"
echo "📁 Main: s3://${BUCKET_MAIN}/ (www/ synced)"
echo ""
echo "📄 HTML:"
echo "<script src=\"//prefetch.ru/${VERSION_FOLDER}/prefetch.min.js\""
echo " integrity=\"${SRI_HASH}\""
echo " crossorigin=\"anonymous\"></script>"
echo ""
echo "=========================================="