feat: Add markdown table conversion pipeline with pulldown-cmark (#180) #56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build & Release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - "src/**" | |
| - "Cargo.toml" | |
| - "Cargo.lock" | |
| - "Dockerfile" | |
| - "Dockerfile.*" | |
| workflow_dispatch: | |
| inputs: | |
| chart_bump: | |
| description: 'Chart version bump type' | |
| required: true | |
| type: choice | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| default: patch | |
| release: | |
| description: 'Stable release (no beta suffix)' | |
| required: false | |
| type: boolean | |
| default: false | |
| dry_run: | |
| description: 'Dry run (show changes without committing)' | |
| required: false | |
| type: boolean | |
| default: false | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| build-image: | |
| strategy: | |
| matrix: | |
| variant: | |
| - { suffix: "", dockerfile: "Dockerfile", artifact: "default" } | |
| - { suffix: "-codex", dockerfile: "Dockerfile.codex", artifact: "codex" } | |
| - { suffix: "-claude", dockerfile: "Dockerfile.claude", artifact: "claude" } | |
| - { suffix: "-gemini", dockerfile: "Dockerfile.gemini", artifact: "gemini" } | |
| platform: | |
| - { os: linux/amd64, runner: ubuntu-latest } | |
| - { os: linux/arm64, runner: ubuntu-24.04-arm } | |
| runs-on: ${{ matrix.platform.runner }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.repository_owner }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }} | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ${{ matrix.variant.dockerfile }} | |
| platforms: ${{ matrix.platform.os }} | |
| outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }},push-by-digest=true,name-canonical=true,push=${{ inputs.dry_run != true }} | |
| cache-from: type=gha,scope=${{ matrix.variant.suffix }}-${{ matrix.platform.os }} | |
| cache-to: type=gha,scope=${{ matrix.variant.suffix }}-${{ matrix.platform.os }},mode=max | |
| - name: Export digest | |
| if: inputs.dry_run != true | |
| run: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| if: inputs.dry_run != true | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: digests-${{ matrix.variant.artifact }}-${{ matrix.platform.runner }} | |
| path: /tmp/digests/* | |
| retention-days: 1 | |
| merge-manifests: | |
| needs: build-image | |
| if: inputs.dry_run != true | |
| strategy: | |
| matrix: | |
| variant: | |
| - { suffix: "", artifact: "default" } | |
| - { suffix: "-codex", artifact: "codex" } | |
| - { suffix: "-claude", artifact: "claude" } | |
| - { suffix: "-gemini", artifact: "gemini" } | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| version: ${{ steps.meta.outputs.version }} | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/digests | |
| pattern: digests-${{ matrix.variant.artifact }}-* | |
| merge-multiple: true | |
| - uses: docker/setup-buildx-action@v3 | |
| - uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.repository_owner }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }} | |
| tags: | | |
| type=sha,prefix= | |
| type=raw,value=latest | |
| - name: Create manifest list | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.variant.suffix }}@sha256:%s ' *) | |
| bump-chart: | |
| needs: merge-manifests | |
| if: inputs.dry_run != true | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Generate App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v1 | |
| with: | |
| app-id: ${{ secrets.APP_ID }} | |
| private-key: ${{ secrets.APP_PRIVATE_KEY }} | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get current chart version | |
| id: current | |
| run: | | |
| chart_version=$(grep '^version:' charts/openab/Chart.yaml | awk '{print $2}') | |
| echo "chart_version=$chart_version" >> "$GITHUB_OUTPUT" | |
| - name: Bump chart version | |
| id: bump | |
| run: | | |
| current="${{ steps.current.outputs.chart_version }}" | |
| # Strip any existing pre-release suffix for base version | |
| base="${current%%-*}" | |
| IFS='.' read -r major minor patch <<< "$base" | |
| bump_type="${{ inputs.chart_bump }}" | |
| bump_type="${bump_type:-patch}" | |
| case "$bump_type" in | |
| major) major=$((major + 1)); minor=0; patch=0 ;; | |
| minor) minor=$((minor + 1)); patch=0 ;; | |
| patch) patch=$((patch + 1)) ;; | |
| esac | |
| # Stable release: clean version. Otherwise: beta with run number. | |
| if [ "${{ inputs.release }}" = "true" ]; then | |
| new_version="${major}.${minor}.${patch}" | |
| else | |
| new_version="${major}.${minor}.${patch}-beta.${GITHUB_RUN_NUMBER}" | |
| fi | |
| echo "new_version=$new_version" >> "$GITHUB_OUTPUT" | |
| - name: Resolve image SHA | |
| id: image-sha | |
| run: | | |
| # Use the commit SHA that triggered this build — this is the SHA | |
| # that merge-manifests tagged the Docker image with (type=sha,prefix=). | |
| # We capture it here explicitly so it survives the bump commit. | |
| IMAGE_SHA="${{ github.sha }}" | |
| IMAGE_SHA="${IMAGE_SHA:0:7}" | |
| echo "sha=${IMAGE_SHA}" >> "$GITHUB_OUTPUT" | |
| - name: Update Chart.yaml and values.yaml | |
| run: | | |
| IMAGE_SHA="${{ steps.image-sha.outputs.sha }}" | |
| sed -i "s/^version: .*/version: ${{ steps.bump.outputs.new_version }}/" charts/openab/Chart.yaml | |
| sed -i "s/^appVersion: .*/appVersion: \"${IMAGE_SHA}\"/" charts/openab/Chart.yaml | |
| sed -i "s|repository: .*|repository: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}|" charts/openab/values.yaml | |
| sed -i "s/tag: .*/tag: \"${IMAGE_SHA}\"/" charts/openab/values.yaml | |
| - name: Create and auto-merge bump PR | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| VERSION="${{ steps.bump.outputs.new_version }}" | |
| IMAGE_SHA="${{ steps.image-sha.outputs.sha }}" | |
| BRANCH="chore/chart-${VERSION}" | |
| git config user.name "openab-app[bot]" | |
| git config user.email "274185012+openab-app[bot]@users.noreply.github.com" | |
| git checkout -b "$BRANCH" | |
| git add charts/openab/Chart.yaml charts/openab/values.yaml | |
| git commit -m "chore: bump chart to ${VERSION} | |
| image: ${IMAGE_SHA}" | |
| git push origin "$BRANCH" | |
| PR_URL=$(gh pr create \ | |
| --title "chore: bump chart to ${VERSION}" \ | |
| --body "Auto-generated chart version bump for image \`${IMAGE_SHA}\`." \ | |
| --base main --head "$BRANCH") | |
| gh pr merge "$PR_URL" --squash --delete-branch |