From 73999df973f3af35da40cabcadb6d8b42bd0cea2 Mon Sep 17 00:00:00 2001 From: yusufaytas Date: Sun, 15 Mar 2026 13:13:03 +0000 Subject: [PATCH] Added release workflow --- .dockerignore | 5 + .github/workflows/release.yml | 175 ++++++++++++++++++++++++++++++++++ Dockerfile | 38 ++++++++ 3 files changed, 218 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/workflows/release.yml create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2b1c3e5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +node_modules +dist +.git +coverage +npm-debug.log diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ac06086 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,175 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version_bump: + description: 'Version bump type' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major + +permissions: + contents: write + packages: write + id-token: write + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Lint + run: npm run lint + + - name: Type Check + run: npm run type-check + + - name: Run tests + run: npm test + + release: + needs: test + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.new_version }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Calculate next version + id: version + run: | + LATEST_TAG=$(git tag -l 'v*' | sort -V | tail -n1) + if [ -z "$LATEST_TAG" ]; then + LATEST_TAG="v0.0.0" + fi + + echo "Latest tag: $LATEST_TAG" + + VERSION=${LATEST_TAG#v} + IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION" + + case "${{ inputs.version_bump }}" in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH + 1)) + ;; + esac + + NEW_VERSION="v${MAJOR}.${MINOR}.${PATCH}" + echo "New version: $NEW_VERSION" + echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT + + - name: Create and push tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag -a ${{ steps.version.outputs.new_version }} -m "Release ${{ steps.version.outputs.new_version }}" + git push origin ${{ steps.version.outputs.new_version }} + + build-docker: + needs: release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ needs.release.outputs.version }} + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + + github-release: + needs: [release, build-docker] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate changelog + run: | + PREVIOUS_TAG=$(git tag -l 'v*' | sort -V | tail -n2 | head -n1) + if [ -z "$PREVIOUS_TAG" ]; then + PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD) + fi + + echo "## Changes since $PREVIOUS_TAG" > changelog.md + echo "" >> changelog.md + git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..${{ needs.release.outputs.version }} >> changelog.md || true + echo "" >> changelog.md + echo "## Docker Image" >> changelog.md + echo "" >> changelog.md + echo "Docker image is available at:" >> changelog.md + echo "- \`ghcr.io/${{ github.repository }}:${{ needs.release.outputs.version }}\`" >> changelog.md + echo "- \`ghcr.io/${{ github.repository }}:latest\`" >> changelog.md + echo "" >> changelog.md + echo "Pull with: \`docker pull ghcr.io/${{ github.repository }}:${{ needs.release.outputs.version }}\`" >> changelog.md + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ needs.release.outputs.version }} + name: Release ${{ needs.release.outputs.version }} + body_path: changelog.md + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..756dd1b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +FROM node:20-bookworm-slim AS base + +FROM base AS build-tools +RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ && rm -rf /var/lib/apt/lists/* + +FROM build-tools AS deps +WORKDIR /app +COPY package*.json ./ +RUN npm ci + +FROM build-tools AS prod-deps +WORKDIR /app +COPY package*.json ./ +RUN npm ci --omit=dev + +FROM build-tools AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +RUN npm run build + +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production + +COPY --from=prod-deps /app/node_modules ./node_modules +COPY --from=builder /app/dist ./dist + +RUN groupadd --system --gid 1001 nodejs && useradd --system --uid 1001 --gid 1001 copilot +RUN chown -R copilot:nodejs /app +USER copilot + +EXPOSE 6060 + +ENV PORT=6060 + +CMD ["node", "dist/server.js"]