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
11 changes: 11 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@

---

## Release tag (optional)

When this PR is merged to `main`, a semantic tag will be created automatically. To control the version:

- **Option A:** Add a label to this PR: `release:vX.Y.Z` (e.g. `release:v1.2.3`). Create the label in the repo if it doesn’t exist.
- **Option B:** Add a line in this PR’s description: `Release: vX.Y.Z` (e.g. `Release: v1.2.3`).

If you don’t specify a version, the workflow will bump the patch from the latest tag (e.g. `v1.2.3` → `v1.2.4`).

---

## Pre-merge author checklist

- [ ] I've clearly explained:
Expand Down
83 changes: 83 additions & 0 deletions .github/workflows/build_and_publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Build and Push AIM AHEAD APP Container

on:
push:
branches:
- main
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest

# Required for pushing to ghcr.io
permissions:
contents: read
packages: write
attestations: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # need full history so latest git tag is available

- name: Get latest semantic git tag
id: get_tag
run: |
TAG=$(git tag -l 'v*.*.*' --sort=-v:refname | head -n 1)
echo "latest=${TAG:-}" >> $GITHUB_OUTPUT
echo "Latest git tag: ${TAG:-<none>}"

- 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
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=semver,pattern=v{{version}}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
type=raw,value=${{ steps.get_tag.outputs.latest }},enable=${{ github.ref == 'refs/heads/main' && steps.get_tag.outputs.latest != '' }}
type=sha,prefix=,format=short

- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
with:
context: .
file: ./build/Dockerfile
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Generate artifact attestation
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
46 changes: 46 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Test AIM AHEAD APP

on:
push:
branches-ignore:
- main
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"
- name: Install dependencies
run: |
npm ci
- name: Check and lint code formatting
run: |
npm run lint-staged
- name: check-secrets
uses: secret-scanner/action@0.0.2
codeql:
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 360
permissions:
security-events: write
packages: read
strategy:
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: javascript-typescript
build-mode: none
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:javascript-typescript"

132 changes: 0 additions & 132 deletions .github/workflows/ci.yml

This file was deleted.

81 changes: 81 additions & 0 deletions .github/workflows/release_tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Create semantic tag on merge

on:
pull_request:
types: [closed]
branches: [main]

jobs:
tag-release:
# Only run when the PR was merged (not just closed) into main
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main'
runs-on: ubuntu-latest
permissions:
contents: write # Required to create and push a tag

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history and tags

# Resolve tag: user-specified (label or PR body) or auto-bump
- name: Resolve release tag
id: resolve_tag
env:
PR_BODY: ${{ github.event.pull_request.body }}
run: |
# --- Option 1: PR label "release:v1.2.3" or "release:1.2.3" ---
LABELS='${{ toJSON(github.event.pull_request.labels.*.name) }}'
TAG_FROM_LABEL=$(echo "$LABELS" | jq -r '.[] | select(startswith("release:")) | sub("^release:"; "")' | head -n 1)
if [ -n "$TAG_FROM_LABEL" ] && [ "$TAG_FROM_LABEL" != "null" ]; then
# Ensure v prefix
[[ "$TAG_FROM_LABEL" != v* ]] && TAG_FROM_LABEL="v${TAG_FROM_LABEL}"
echo "tag_from=label" >> $GITHUB_OUTPUT
echo "new_tag=$TAG_FROM_LABEL" >> $GITHUB_OUTPUT
echo "Using tag from label: $TAG_FROM_LABEL"
exit 0
fi

# --- Option 2: PR body line "Release: v1.2.3" or "release: 1.2.3" ---
TAG_FROM_BODY=$(echo "$PR_BODY" | grep -iE '^\s*release:\s*v?[0-9]+\.[0-9]+\.[0-9]+' | head -n 1 | sed -E 's/^[^:]*:\s*//i' | tr -d ' \r')
if [ -n "$TAG_FROM_BODY" ]; then
[[ "$TAG_FROM_BODY" != v* ]] && TAG_FROM_BODY="v${TAG_FROM_BODY}"
echo "tag_from=body" >> $GITHUB_OUTPUT
echo "new_tag=$TAG_FROM_BODY" >> $GITHUB_OUTPUT
echo "Using tag from PR body: $TAG_FROM_BODY"
exit 0
fi

# --- Fallback: auto-bump patch from latest tag ---
LATEST_TAG=$(git tag -l 'v*.*.*' --sort=-v:refname | head -n 1)
[ -z "$LATEST_TAG" ] && LATEST_TAG="v0.0.0"
VERSION="${LATEST_TAG#v}"
MAJOR="${VERSION%%.*}"; REST="${VERSION#*.}"
MINOR="${REST%%.*}"; PATCH="${REST#*.}"
PATCH=$((PATCH + 1))
NEW_TAG="v${MAJOR}.${MINOR}.${PATCH}"
echo "tag_from=auto" >> $GITHUB_OUTPUT
echo "new_tag=$NEW_TAG" >> $GITHUB_OUTPUT
echo "No user tag found; auto-bumped to: $NEW_TAG"

- name: Validate tag format
run: |
TAG="${{ steps.resolve_tag.outputs.new_tag }}"
if ! echo "$TAG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error::Invalid semantic tag: $TAG (expected e.g. v1.2.3)"
exit 1
fi
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "::error::Tag $TAG already exists"
exit 1
fi
echo "Tag $TAG is valid and does not exist"

- name: Create and push tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
TAG="${{ steps.resolve_tag.outputs.new_tag }}"
git tag -a "$TAG" -m "Release $TAG (PR #${{ github.event.pull_request.number }})"
git push origin "$TAG"
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ template.beconf.tfvars
# testing
/coverage

# production
/build

# misc
.env.local
.env.development.local
Expand Down
20 changes: 0 additions & 20 deletions Dockerfile

This file was deleted.

Loading
Loading