diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..88d08d0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +--- + +version: 2 + +updates: + # Automatically propose PRs for out-of-date GitHub actions + - package-ecosystem: github-actions + directory: "/" + schedule: + # Check for new versions weekly + interval: weekly + # Update all actions in a single PR + groups: + github-actions: + patterns: ["*"] + labels: + - automation + - gha-update + +# TODO: Add web app python dependencies diff --git a/.github/workflows/build-push-artifacts.yml b/.github/workflows/build-push-artifacts.yml index 73d8370..332c17f 100644 --- a/.github/workflows/build-push-artifacts.yml +++ b/.github/workflows/build-push-artifacts.yml @@ -1,54 +1,45 @@ # Adapted from https://github.com/stackhpc/azimuth/blob/master/.github/workflows/build-push-artifacts.yaml name: Publish artifacts -# Run the tasks on every push -on: push -jobs: - # Job to run change detection - changes: - name: Check for relevant changes - runs-on: ubuntu-latest - # Required permissions - permissions: - pull-requests: read - # Set job outputs to values from filter step - outputs: - images: ${{ steps.filter.outputs.images }} - chart: ${{ steps.filter.outputs.chart }} - steps: - - - name: Check out the repository - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v2 - id: filter - with: - base: ${{ github.ref_name }} - # TODO: Make image filters more granular - filters: | - images: - - 'web-apps/**' - chart: - - 'charts/**' +on: + # Publish artifacts on every push to master and every tag + push: + branches: + - master + tags: + - "*" + # Also allow publication to be done via a workflow call + # In this case, the chart version is returned as an output + workflow_call: + inputs: + ref: + type: string + description: The ref to build. + required: true + outputs: + chart-version: + description: The chart version that was published + value: ${{ jobs.build_push_chart.outputs.chart-version }} - # Job to build container images +jobs: build_push_images: name: Build and push images runs-on: ubuntu-latest - permissions: - contents: read - id-token: write # needed for signing the images with GitHub OIDC Token - packages: write # required for pushing container images - security-events: write # required for pushing SARIF files - needs: changes - if: ${{ github.ref_type == 'tag' || needs.changes.outputs.images == 'true' }} strategy: matrix: include: - component: chat - component: image-analysis + permissions: + contents: read + id-token: write # needed for signing the images with GitHub OIDC Token + packages: write # required for pushing container images + security-events: write # required for pushing SARIF files steps: - name: Check out the repository uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref || github.ref }} - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -57,6 +48,10 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Get SemVer version for current commit + id: semver + uses: azimuth-cloud/github-actions/semver@master + - name: Calculate metadata for image id: image-meta uses: docker/metadata-action@v5 @@ -66,7 +61,7 @@ jobs: tags: | type=ref,event=branch type=ref,event=tag - type=sha,prefix= + type=raw,value=${{ steps.semver.outputs.short-sha }} - name: Build and push image uses: azimuth-cloud/github-actions/docker-multiarch-build-push@master @@ -79,17 +74,18 @@ jobs: tags: ${{ steps.image-meta.outputs.tags }} labels: ${{ steps.image-meta.outputs.labels }} - # Job to build and publish Helm chart build_push_chart: name: Build and push Helm chart runs-on: ubuntu-latest - # Only build and push the chart if chart files have changed - needs: [changes] - if: ${{ github.ref_type == 'tag' || needs.changes.outputs.chart == 'true' }} + # Only build and push the chart if the images built successfully + needs: [build_push_images] + outputs: + chart-version: ${{ steps.semver.outputs.version }} steps: - name: Check out the repository uses: actions/checkout@v4 with: + ref: ${{ inputs.ref || github.ref }} # This is important for the semver action to work correctly # when determining the number of commits since the last tag fetch-depth: 0 @@ -101,7 +97,6 @@ jobs: - name: Publish Helm charts uses: azimuth-cloud/github-actions/helm-publish@master with: - directory: charts token: ${{ secrets.GITHUB_TOKEN }} version: ${{ steps.semver.outputs.version }} app-version: ${{ steps.semver.outputs.short-sha }} diff --git a/.github/workflows/test-pr.yml b/.github/workflows/test-pr.yml index a064702..bdb32d1 100644 --- a/.github/workflows/test-pr.yml +++ b/.github/workflows/test-pr.yml @@ -1,16 +1,40 @@ +# Based on https://github.com/azimuth-cloud/azimuth/blob/master/.github/workflows/test-pr.yaml name: Test pull request + on: - pull_request: + # We use pull_request_target so that dependabot-created workflows can run + pull_request_target: types: - opened - - reopened - - ready_for_review - synchronize + - ready_for_review + - reopened + branches: + - master + +# Use the head ref for workflow concurrency, with cancellation +# This should mean that any previous workflows for a PR get cancelled when a new commit is pushed concurrency: group: ${{ github.workflow }}-${{ github.head_ref }} cancel-in-progress: true + jobs: + # This job exists so that PRs from outside the main repo are rejected + fail_on_remote: + runs-on: ubuntu-latest + steps: + - name: PR must be from a branch in the stackhpc/azimuth-llm repo + run: exit ${{ github.event.pull_request.head.repo.full_name == 'stackhpc/azimuth-llm' && '0' || '1' }} + + publish_artifacts: + needs: [fail_on_remote] + uses: ./.github/workflows/build-push-artifacts.yml + with: + ref: ${{ github.event.pull_request.head.sha }} + secrets: inherit + chart_validation: + needs: [publish_artifacts] runs-on: ubuntu-latest env: CLUSTER_NAME: chart-testing diff --git a/charts/azimuth-chat/Chart.yaml b/charts/azimuth-chat/Chart.yaml index 97dd341..9902e93 100644 --- a/charts/azimuth-chat/Chart.yaml +++ b/charts/azimuth-chat/Chart.yaml @@ -1,20 +1,20 @@ apiVersion: v2 name: azimuth-llm-chat -description: HuggingFace vision model serving along with a simple web interface. +description: HuggingFace large language model serving along with a simple web interface. maintainers: - name: "Scott Davidson" email: scott@stackhpc.com type: application +# The version and appVersion are updated by the chart build script version: 0.1.0 - -appVersion: "0.1.0" +appVersion: master icon: https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo.svg annotations: - azimuth.stackhpc.com/label: HuggingFace Image Analysis + azimuth.stackhpc.com/label: HuggingFace LLM dependencies: - name: azimuth-llm diff --git a/charts/azimuth-image-analysis/Chart.yaml b/charts/azimuth-image-analysis/Chart.yaml index 238016b..3cc52f2 100644 --- a/charts/azimuth-image-analysis/Chart.yaml +++ b/charts/azimuth-image-analysis/Chart.yaml @@ -1,20 +1,20 @@ apiVersion: v2 name: azimuth-llm-image-analysis -description: HuggingFace vision model serving along with a simple web interface. +description: HuggingFace vision model serving along with a simple web interface for image analysis. maintainers: - name: "Scott Davidson" email: scott@stackhpc.com type: application +# The version and appVersion are updated by the chart build script version: 0.1.0 - -appVersion: "0.1.0" +appVersion: master icon: https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo.svg annotations: - azimuth.stackhpc.com/label: HuggingFace Image Analysis + azimuth.stackhpc.com/label: HuggingFace VLM dependencies: - name: azimuth-llm diff --git a/charts/azimuth-llm/Chart.yaml b/charts/azimuth-llm/Chart.yaml index 6c92b69..182ba2f 100644 --- a/charts/azimuth-llm/Chart.yaml +++ b/charts/azimuth-llm/Chart.yaml @@ -5,26 +5,11 @@ maintainers: - name: "Scott Davidson" email: scott@stackhpc.com -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. type: application -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.2.0 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: "1.16.0" +# The version and appVersion are updated by the chart build script +version: 0.1.0 +appVersion: master icon: https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo.svg diff --git a/charts/azimuth-llm/templates/ui/deployment.yml b/charts/azimuth-llm/templates/ui/deployment.yml index 3938893..268b30a 100644 --- a/charts/azimuth-llm/templates/ui/deployment.yml +++ b/charts/azimuth-llm/templates/ui/deployment.yml @@ -24,7 +24,7 @@ spec: containers: - name: {{ .Release.Name }}-ui {{- with .Values.ui.image }} - image: {{ printf "%s:%s" .repository .version }} + image: {{ printf "%s:%s" .repository (default $.Chart.AppVersion .tag) }} {{- if .imagePullPolicy }} imagePullPolicy: {{ .imagePullPolicy }} {{- end -}} diff --git a/charts/azimuth-llm/values.yaml b/charts/azimuth-llm/values.yaml index dc3a95f..253056c 100644 --- a/charts/azimuth-llm/values.yaml +++ b/charts/azimuth-llm/values.yaml @@ -83,7 +83,7 @@ ui: # Container image config image: repository: ghcr.io/stackhpc/azimuth-llm-chat-ui - version: ef83288 + tag: # Defaults to chart's appVersion imagePullPolicy: # The settings to be passed to the frontend web app. # Format depends on the chosen UI image above. For each of the UIs