From 62219f50092e60ead3be9d5a987f383d3c8855a9 Mon Sep 17 00:00:00 2001 From: Yuval Turgeman Date: Thu, 20 Nov 2025 14:23:41 -0500 Subject: [PATCH 1/6] Add automated release workflow for dev/prod - Replace dynamic versioning with fixed versions in pyproject.toml - Auto-build dev builds on push to dev (dev-{sha} tags) - Add "Create Release PR" workflow that creates dev to main PR - On merge of release PR a tag is generated and a release is built Signed-off-by: Yuval Turgeman Assisted-by: Claude --- .../{build-and-push.yaml => build-dev.yml} | 23 ++--- .github/workflows/create-release-pr.yml | 94 +++++++++++++++++++ .github/workflows/release.yml | 84 +++++++++++++++++ deploy/local/Makefile | 4 +- deploy/local/podman-compose.yml | 2 - frontend/Containerfile | 8 -- frontend/pyproject.toml | 4 +- frontend/start.sh | 8 -- 8 files changed, 191 insertions(+), 36 deletions(-) rename .github/workflows/{build-and-push.yaml => build-dev.yml} (59%) create mode 100644 .github/workflows/create-release-pr.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build-and-push.yaml b/.github/workflows/build-dev.yml similarity index 59% rename from .github/workflows/build-and-push.yaml rename to .github/workflows/build-dev.yml index eb38f09e..877be4dc 100644 --- a/.github/workflows/build-and-push.yaml +++ b/.github/workflows/build-dev.yml @@ -1,21 +1,18 @@ -name: Build and push image +name: Build dev image on: push: branches: - - 'main' - workflow_dispatch: + - dev jobs: - build-and-push: - if: github.repository == 'rh-ai-quickstart/RAG' + build-dev: runs-on: ubuntu-latest strategy: matrix: include: - name: llamastack-dist-ui context: frontend - chart: deploy/helm/rag/Chart.yaml steps: - name: Checkout uses: actions/checkout@v4 @@ -30,18 +27,16 @@ jobs: username: ${{ secrets.QUAY_USERNAME }} password: ${{ secrets.QUAY_PASSWORD }} - - name: Extract version from Chart.yaml - id: version + - name: Generate dev tag + id: tag run: | - version=$(grep '^version:' ${{ matrix.chart }} | awk '{print $2}') - echo "tag=$version" >> $GITHUB_OUTPUT + short_sha=$(git rev-parse --short HEAD) + echo "value=dev-${short_sha}" >> $GITHUB_OUTPUT - - name: Build and push ${{ matrix.name }} + - name: Build and push uses: docker/build-push-action@v5 with: context: ${{ matrix.context }} file: ${{ matrix.context }}/Containerfile push: true - tags: quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.version.outputs.tag }} - build-args: | - IMAGE_TAG=${{ steps.version.outputs.tag }} + tags: quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.tag.outputs.value }} diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml new file mode 100644 index 00000000..7ea41437 --- /dev/null +++ b/.github/workflows/create-release-pr.yml @@ -0,0 +1,94 @@ +name: Create Release PR + +on: + workflow_dispatch: + branches: + - dev + inputs: + version_bump: + description: 'Version bump type' + required: true + type: choice + options: + - patch + - minor + - major + default: 'patch' + +jobs: + create-release-pr: + runs-on: ubuntu-latest + steps: + - name: Checkout dev branch + uses: actions/checkout@v4 + with: + ref: dev + fetch-depth: 0 + + - name: Get current version + id: current_version + run: | + version=$(grep '^version:' deploy/helm/rag/Chart.yaml | awk '{print $2}') + echo "version=$version" >> $GITHUB_OUTPUT + + - name: Calculate new version + id: new_version + run: | + current="${{ steps.current_version.outputs.version }}" + IFS='.' read -r major minor patch <<< "$current" + + case "${{ inputs.version_bump }}" in + major) + new_version="$((major + 1)).0.0" + ;; + minor) + new_version="${major}.$((minor + 1)).0" + ;; + patch) + new_version="${major}.${minor}.$((patch + 1))" + ;; + esac + + echo "version=$new_version" >> $GITHUB_OUTPUT + echo "New version will be: $new_version" + + - name: Update Chart version + run: | + sed -i "s/^version: .*/version: ${{ steps.new_version.outputs.version }}/" deploy/helm/rag/Chart.yaml + sed -i "s/^appVersion: .*/appVersion: \"${{ steps.new_version.outputs.version }}\"/" deploy/helm/rag/Chart.yaml + + - name: Commit version bump + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b release/v${{ steps.new_version.outputs.version }} + git add deploy/helm/rag/Chart.yaml + git commit -m "chore: bump version to ${{ steps.new_version.outputs.version }}" + git push origin release/v${{ steps.new_version.outputs.version }} + + - name: Create Pull Request + env: + GH_TOKEN: ${{ github.token }} + run: | + gh pr create \ + --title "Release v${{ steps.new_version.outputs.version }}" \ + --body "$(cat <<'EOF' + ## Release v${{ steps.new_version.outputs.version }} + + This PR merges changes from \`dev\` to \`main\` for release v${{ steps.new_version.outputs.version }}. + + ### Changes + $(git log main..dev --oneline --no-merges | head -20) + + ### Checklist + - [ ] All tests passing + - [ ] Documentation updated + - [ ] Breaking changes documented (if any) + + After merging, this will automatically: + - Create git tag v${{ steps.new_version.outputs.version }} + - Build and push Docker images + EOF + )" \ + --base main \ + --head release/v${{ steps.new_version.outputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..9fd756f4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,84 @@ +name: Release + +on: + pull_request: + types: [closed] + branches: + - main + +jobs: + release: + if: | + github.event.pull_request.merged == true && + startsWith(github.event.pull_request.head.ref, 'release/') + runs-on: ubuntu-latest + strategy: + matrix: + include: + - name: llamastack-dist-ui + context: frontend + chart: deploy/helm/rag/Chart.yaml + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get version from Chart.yaml + id: version + run: | + version=$(grep '^version:' ${{ matrix.chart }} | awk '{print $2}') + echo "value=$version" >> $GITHUB_OUTPUT + + - name: Delete release branch + run: | + git push origin --delete ${{ github.event.pull_request.head.ref }} || true + + - name: Create git tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag -a "v${{ steps.version.outputs.value }}" -m "Release v${{ steps.version.outputs.value }}" || true + git push origin "v${{ steps.version.outputs.value }}" || true + + - name: Install Helm + uses: azure/setup-helm@v4 + with: + version: 'latest' + + - name: Update Helm dependencies + run: | + helm dependency update deploy/helm/rag + + - name: Package Helm chart + run: | + helm package deploy/helm/rag -d . + ls -la rag-*.tgz + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "v${{ steps.version.outputs.value }}" \ + --title "Release v${{ steps.version.outputs.value }}" \ + --notes "Release v${{ steps.version.outputs.value }}" \ + --latest \ + rag-${{ steps.version.outputs.value }}.tgz || true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Quay.io + uses: docker/login-action@v3 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_PASSWORD }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: ${{ matrix.context }} + file: ${{ matrix.context }}/Containerfile + push: true + tags: quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.version.outputs.value }} diff --git a/deploy/local/Makefile b/deploy/local/Makefile index a7d8376b..11018672 100644 --- a/deploy/local/Makefile +++ b/deploy/local/Makefile @@ -19,7 +19,7 @@ PROJECT_NAME := rag OLLAMA_MODEL := llama3.2:3b-instruct-fp16 # UI Build Configuration -VERSION ?= 0.2.22 +VERSION ?= 0.2.23 TAVILY_SEARCH_API_KEY ?= "" CONTAINER_REGISTRY ?= quay.io/rh-ai-quickstart DIST_UI_DIR := $(abspath ../../frontend) @@ -296,7 +296,7 @@ config: ## Show current configuration # UI Build and Deployment Targets build-ui: ## Build the RAG UI container locally @echo "$(BLUE)[INFO]$(NC) Building RAG UI container for $(PLATFORM)..." - @podman build --platform $(PLATFORM) --build-arg IMAGE_TAG=$(VERSION) -t llamastack-dist-ui:$(VERSION) -f $(DIST_UI_DIR)/Containerfile $(DIST_UI_DIR) + @podman build --platform $(PLATFORM) -t llamastack-dist-ui:$(VERSION) -f $(DIST_UI_DIR)/Containerfile $(DIST_UI_DIR) @echo "$(GREEN)[SUCCESS]$(NC) RAG UI container built successfully." build-and-push-ui: build-ui ## Build and push UI container to registry diff --git a/deploy/local/podman-compose.yml b/deploy/local/podman-compose.yml index 4dc94e81..b6e4c88f 100644 --- a/deploy/local/podman-compose.yml +++ b/deploy/local/podman-compose.yml @@ -62,8 +62,6 @@ services: build: context: ../../frontend dockerfile: Containerfile - args: - IMAGE_TAG: "0.2.9" container_name: rag-ui depends_on: llamastack: diff --git a/frontend/Containerfile b/frontend/Containerfile index bd81a1e0..c76fcb0e 100644 --- a/frontend/Containerfile +++ b/frontend/Containerfile @@ -3,17 +3,9 @@ FROM python:3.12-slim -ARG IMAGE_TAG WORKDIR /app COPY . /app/ - -# Make sure IMAGE_TAG is set -RUN if [ -z "$IMAGE_TAG" ]; then echo "IMAGE_TAG is not set"; exit 1; fi - -# Replace __LLAMASTACK_VERSION__ with actual version in pyproject.toml -RUN sed -i "s/__LLAMASTACK_VERSION__/${IMAGE_TAG}/g" pyproject.toml - # Install uv RUN pip install uv diff --git a/frontend/pyproject.toml b/frontend/pyproject.toml index 06df99f2..be65e231 100644 --- a/frontend/pyproject.toml +++ b/frontend/pyproject.toml @@ -10,10 +10,10 @@ requires-python = ">=3.12" dependencies = [ "streamlit", "pandas", - "llama-stack-client==__LLAMASTACK_VERSION__", + "llama-stack-client==0.2.23", "requests", "streamlit-option-menu", - "llama-stack==__LLAMASTACK_VERSION__", + "llama-stack==0.2.23", "fire", ] diff --git a/frontend/start.sh b/frontend/start.sh index a1974f67..fd0edd93 100755 --- a/frontend/start.sh +++ b/frontend/start.sh @@ -2,14 +2,6 @@ cd "$(dirname "$0")" -# Set default VERSION if not provided -VERSION=${VERSION:-0.2.22} - -# Replace __LLAMASTACK_VERSION__ with actual version in pyproject.toml -echo "Replacing __LLAMASTACK_VERSION__ with $VERSION in pyproject.toml" -sed -i.bak "s/__LLAMASTACK_VERSION__/$VERSION/g" pyproject.toml -rm -f pyproject.toml.bak - # Export TAVILY_SEARCH_API_KEY if it's set if [ -n "$TAVILY_SEARCH_API_KEY" ]; then export TAVILY_SEARCH_API_KEY From 292fd37675f87193c599b2fe6f5670be80762dfd Mon Sep 17 00:00:00 2001 From: Yuval Turgeman Date: Fri, 21 Nov 2025 11:39:15 -0500 Subject: [PATCH 2/6] update workflow and build Modify Containerfile to better use cached layers Build image on every push, both to PRs and commits inside PRs Signed-off-by: Yuval Turgeman --- .github/workflows/build-dev.yml | 5 +++++ frontend/Containerfile | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 877be4dc..ba968e42 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -1,6 +1,9 @@ name: Build dev image on: + pull_request: + branches: + - dev push: branches: - dev @@ -40,3 +43,5 @@ jobs: file: ${{ matrix.context }}/Containerfile push: true tags: quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.tag.outputs.value }} + cache-from: type=registry,ref=quay.io/rh-ai-quickstart/${{ matrix.name }}:buildcache + cache-to: type=registry,ref=quay.io/rh-ai-quickstart/${{ matrix.name }}:buildcache,mode=max diff --git a/frontend/Containerfile b/frontend/Containerfile index c76fcb0e..b1f9e60b 100644 --- a/frontend/Containerfile +++ b/frontend/Containerfile @@ -4,9 +4,8 @@ FROM python:3.12-slim WORKDIR /app -COPY . /app/ -# Install uv +# Install uv first (rarely changes) RUN pip install uv # Set UV cache directory to a writable location @@ -17,7 +16,10 @@ ENV XDG_CACHE_HOME=/app/.cache RUN mkdir -p /app/.uv-cache /app/.cache && \ chmod -R 777 /app/.uv-cache /app/.cache -# Install dependencies using uv +# Copy dependency files first (for better caching) +COPY pyproject.toml uv.lock* ./ + +# Install dependencies using uv (this layer is cached unless dependencies change) RUN if [ -f "uv.lock" ]; then \ echo "Lockfile found, using frozen sync"; \ uv sync --frozen; \ @@ -26,6 +28,9 @@ RUN if [ -f "uv.lock" ]; then \ uv sync; \ fi +# Copy application code last (invalidates cache only on code changes) +COPY . /app/ + # Ensure all app files have proper ownership and permissions for non-root users RUN chown -R 1001:0 /app && \ chmod -R g+rwX /app From 7d6d0bae8d31a98bb2893bbe3a20515742ebfe2b Mon Sep 17 00:00:00 2001 From: Yuval Turgeman Date: Fri, 21 Nov 2025 11:50:10 -0500 Subject: [PATCH 3/6] add image build comment Signed-off-by: Yuval Turgeman --- .github/workflows/build-dev.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index ba968e42..6c943163 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -34,7 +34,13 @@ jobs: id: tag run: | short_sha=$(git rev-parse --short HEAD) - echo "value=dev-${short_sha}" >> $GITHUB_OUTPUT + if [ "${{ github.event_name }}" == "pull_request" ]; then + # PR build: dev-pr123-abc1234 + echo "value=dev-pr${{ github.event.pull_request.number }}-${short_sha}" >> $GITHUB_OUTPUT + else + # Push to dev: dev-abc1234 + echo "value=dev-${short_sha}" >> $GITHUB_OUTPUT + fi - name: Build and push uses: docker/build-push-action@v5 @@ -45,3 +51,15 @@ jobs: tags: quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.tag.outputs.value }} cache-from: type=registry,ref=quay.io/rh-ai-quickstart/${{ matrix.name }}:buildcache cache-to: type=registry,ref=quay.io/rh-ai-quickstart/${{ matrix.name }}:buildcache,mode=max + + - name: Comment on PR with image tag + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `✅ Built image: \`quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.tag.outputs.value }}\`` + }) From a8a9433acd1d0901b7687566fb29b040b8cbeacf Mon Sep 17 00:00:00 2001 From: Yuval Turgeman Date: Fri, 21 Nov 2025 11:55:26 -0500 Subject: [PATCH 4/6] test Signed-off-by: Yuval Turgeman --- .github/workflows/build-dev.yml | 8 ++++---- .github/workflows/release.yml | 2 +- frontend/Containerfile | 24 +++++++++--------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 6c943163..4c6b4b21 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -48,9 +48,9 @@ jobs: context: ${{ matrix.context }} file: ${{ matrix.context }}/Containerfile push: true - tags: quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.tag.outputs.value }} - cache-from: type=registry,ref=quay.io/rh-ai-quickstart/${{ matrix.name }}:buildcache - cache-to: type=registry,ref=quay.io/rh-ai-quickstart/${{ matrix.name }}:buildcache,mode=max + tags: quay.io/yuvalturg/${{ matrix.name }}:${{ steps.tag.outputs.value }} + cache-from: type=registry,ref=quay.io/yuvalturg/${{ matrix.name }}:buildcache + cache-to: type=registry,ref=quay.io/yuvalturg/${{ matrix.name }}:buildcache,mode=max - name: Comment on PR with image tag if: github.event_name == 'pull_request' @@ -61,5 +61,5 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `✅ Built image: \`quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.tag.outputs.value }}\`` + body: `✅ Built image: \`quay.io/yuvalturg/${{ matrix.name }}:${{ steps.tag.outputs.value }}\`` }) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9fd756f4..a1b2f487 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,4 +81,4 @@ jobs: context: ${{ matrix.context }} file: ${{ matrix.context }}/Containerfile push: true - tags: quay.io/rh-ai-quickstart/${{ matrix.name }}:${{ steps.version.outputs.value }} + tags: quay.io/yuvalturg/${{ matrix.name }}:${{ steps.version.outputs.value }} diff --git a/frontend/Containerfile b/frontend/Containerfile index b1f9e60b..64c032cd 100644 --- a/frontend/Containerfile +++ b/frontend/Containerfile @@ -8,6 +8,15 @@ WORKDIR /app # Install uv first (rarely changes) RUN pip install uv +# Copy dependency file first (for better caching) +COPY pyproject.toml ./ + +# Install dependencies only (cached unless pyproject.toml changes) +RUN uv pip install --system -r pyproject.toml + +# Copy application code (invalidates cache only on code changes) +COPY . /app/ + # Set UV cache directory to a writable location ENV UV_CACHE_DIR=/app/.uv-cache ENV XDG_CACHE_HOME=/app/.cache @@ -16,21 +25,6 @@ ENV XDG_CACHE_HOME=/app/.cache RUN mkdir -p /app/.uv-cache /app/.cache && \ chmod -R 777 /app/.uv-cache /app/.cache -# Copy dependency files first (for better caching) -COPY pyproject.toml uv.lock* ./ - -# Install dependencies using uv (this layer is cached unless dependencies change) -RUN if [ -f "uv.lock" ]; then \ - echo "Lockfile found, using frozen sync"; \ - uv sync --frozen; \ - else \ - echo "Lockfile not found, creating new one"; \ - uv sync; \ - fi - -# Copy application code last (invalidates cache only on code changes) -COPY . /app/ - # Ensure all app files have proper ownership and permissions for non-root users RUN chown -R 1001:0 /app && \ chmod -R g+rwX /app From 8f63bcfbf5664faa33caa38833ae483f3af43546 Mon Sep 17 00:00:00 2001 From: Yuval Turgeman Date: Fri, 21 Nov 2025 12:04:17 -0500 Subject: [PATCH 5/6] wip Signed-off-by: Yuval Turgeman --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fc495c9f..e180ddaa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Centralize company knowledge with an Enterprise RAG Chatbot +asdf + Use retrieval-augmented generation (RAG) to enhance large language models with specialized data sources for more accurate and context-aware responses. From 615930f148c682e09071c874e0e2a377b6a1b0a6 Mon Sep 17 00:00:00 2001 From: Yuval Turgeman Date: Fri, 21 Nov 2025 12:05:48 -0500 Subject: [PATCH 6/6] wip Signed-off-by: Yuval Turgeman --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e180ddaa..1530b3ac 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ asdf +kuku + Use retrieval-augmented generation (RAG) to enhance large language models with specialized data sources for more accurate and context-aware responses.