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
117 changes: 117 additions & 0 deletions .github/workflows/ci-docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
name: Build And Push Docker image

"on":
workflow_call:
inputs:
publish:
type: boolean
description: Whether to publish the image to the registry
required: false
default: false
ref:
type: string
required: true
description: The git ref to build from
tags:
type: string
required: true
description: The tags for the docker image
labels:
type: string
required: true
description: The labels for the docker image

concurrency:
group: ${{ github.workflow }}-${{ inputs.ref }}
cancel-in-progress: true

env:
DOCKERFILE: "Dockerfile"
REGISTRY_IMAGE: ${{ vars.HARBOR_HOST }}/${{ github.repository }}

jobs:
build:
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-24.04
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps:
- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ inputs.ref }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Login to registry
if: ${{ inputs.publish }}
uses: docker/login-action@v4
with:
registry: ${{ vars.HARBOR_HOST }}
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_PASSWORD }}

- name: Build and push by digest
id: build
uses: docker/build-push-action@v7
with:
context: .
file: ${{ env.DOCKERFILE }}
provenance: false
platforms: ${{ matrix.platform }}
labels: ${{ inputs.labels }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=${{ inputs.publish }}

- name: Export digest
if: ${{ inputs.publish }}
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"

- name: Upload digest
if: ${{ inputs.publish }}
uses: actions/upload-artifact@v7
with:
name: digests-${{ matrix.runner }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge:
runs-on: ubuntu-latest
if: ${{ inputs.publish }}
needs: build
steps:
- name: Download digests
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Login to registry
uses: docker/login-action@v4
with:
registry: ${{ vars.HARBOR_HOST }}
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_PASSWORD }}

- name: Create manifest list and push
working-directory: /tmp/digests
env:
TAGS: ${{ inputs.tags }}
run: |
tag_args=$(echo "$TAGS" | xargs printf -- '--tag %s\n')
digest_args=$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
docker buildx imagetools create $tag_args $digest_args
19 changes: 9 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
name: CI

on:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:smart:

"on":
push:
branches: [main]
pull_request:
Expand Down Expand Up @@ -51,12 +52,10 @@ jobs:

docker:
name: Docker
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v4
- uses: docker/build-push-action@v7
with:
context: .
push: false
platforms: linux/amd64
uses: ./.github/workflows/ci-docker-image.yml
secrets: inherit
with:
publish: false
ref: ${{ github.sha }}
tags: ${{ github.repository }}:ci
labels: ""
123 changes: 89 additions & 34 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,52 @@
---
# yamllint disable rule:line-length
name: Release

on:
push:
tags:
- "v*"

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
"on":
release:
types:
- published

jobs:
check-release:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.release.outputs.version }}
major_minor_version: ${{ steps.release.outputs.major_minor_version }}
is_prerelease: ${{ steps.release.outputs.is_prerelease }}
latest_tag: ${{ steps.release.outputs.latest_tag }}
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Extract version from Cargo.toml
id: release
run: |
version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
major=$(echo "$version" | cut -d. -f1)
minor=$(echo "$version" | cut -d. -f2)
patch=$(echo "$version" | cut -d. -f3 | cut -d- -f1)
prerelease=$(echo "$version" | grep -c '-')

echo "version=$version" >> "$GITHUB_OUTPUT"
echo "major_minor_version=$major.$minor" >> "$GITHUB_OUTPUT"
echo "is_prerelease=$prerelease" >> "$GITHUB_OUTPUT"

latest_tag=$(curl -sL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ github.token }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{ github.repository }}/releases/latest" \
| jq -r '.tag_name')
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"

- name: Check tag matches Cargo.toml version
if: github.event.release.tag_name != format('v{0}', steps.release.outputs.version)
run: |
echo "Tag ${{ github.event.release.tag_name }} does not match Cargo.toml version v${{ steps.release.outputs.version }}"
exit 1

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
Expand All @@ -23,38 +58,58 @@ jobs:
- run: cargo clippy -- -D warnings
- run: cargo test

docker:
name: Docker
metadata:
needs: check-release
runs-on: ubuntu-latest
outputs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
steps:
- name: Set docker image metadata
id: meta
uses: docker/metadata-action@v6
with:
images: |
${{ vars.HARBOR_HOST }}/${{ github.repository }}
tags: |
type=raw,value=${{ needs.check-release.outputs.version }}
type=raw,value=${{ github.event.release.prerelease == false && needs.check-release.outputs.major_minor_version || '' }}
type=raw,value=${{ github.event.release.prerelease == true && 'preview' || 'stable' }}
labels: |
org.opencontainers.image.source=${{ github.repository }}
flavor: |
latest=${{ needs.check-release.outputs.latest_tag == github.event.release.tag_name }}

publish-docker-image:
uses: ./.github/workflows/ci-docker-image.yml
secrets: inherit
needs:
- test
- metadata
with:
publish: true
ref: ${{ github.sha }}
tags: ${{ needs.metadata.outputs.tags }}
labels: ${{ needs.metadata.outputs.labels }}

publish-binaries:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
contents: write
steps:
- uses: actions/checkout@v6

- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0

- uses: docker/setup-buildx-action@v4
- uses: dtolnay/rust-toolchain@stable

- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}
- uses: mlugg/setup-zig@v2

- uses: docker/build-push-action@v7
- uses: goreleaser/goreleaser-action@v7
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
distribution: goreleaser
version: "~> v2"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56 changes: 56 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
version: 2

before:
hooks:
- rustup default stable
- cargo install --locked cargo-zigbuild

builds:
- id: infrahub-git-credential
builder: rust
binary: infrahub-git-credential
command: zigbuild
flags:
- --release
- --bin
- infrahub-git-credential
targets:
- x86_64-unknown-linux-musl
- aarch64-unknown-linux-musl
- x86_64-apple-darwin
- aarch64-apple-darwin

- id: infrahub-git-askpass
builder: rust
binary: infrahub-git-askpass
command: zigbuild
flags:
- --release
- --bin
- infrahub-git-askpass
targets:
- x86_64-unknown-linux-musl
- aarch64-unknown-linux-musl
- x86_64-apple-darwin
- aarch64-apple-darwin

universal_binaries:
- ids:
- infrahub-git-credential
replace: true
- ids:
- infrahub-git-askpass
replace: true

archives:
- formats:
- tar.gz
name_template: >-
{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}

checksum:
name_template: checksums.txt

release:
prerelease: auto
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version = "0.1.0"
edition = "2024"
rust-version = "1.94"
license = "Apache-2.0"
description = "Git credential helpers for Infrahub"
repository = "https://github.com/opsmill/infrahub-credential-helper"
description = "Git credential helper for Infrahub"
repository = "https://github.com/opsmill/infrahub-git-credential-helper"

[dependencies]
clap = { version = "4", features = ["derive", "env"] }
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ clean:
cargo clean

docker:
docker build -t infrahub-git-credential .
docker build -t registry.opsmill.io/opsmill/infrahub-git-credential-helper .
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ Binaries are output to `target/release/infrahub-git-credential` and `target/rele
The project includes a multi-stage Dockerfile that produces statically linked binaries (musl) in a scratch-based image. Supports both `amd64` and `arm64` architectures.

```sh
docker build -t infrahub-git-credential .
docker build -t registry.opsmill.io/opsmill/infrahub-git-credential-helper .
```

Use in a downstream Dockerfile:

```dockerfile
COPY --from=infrahub-git-credential /usr/bin/infrahub-git-credential /usr/bin/infrahub-git-credential
COPY --from=infrahub-git-credential /usr/bin/infrahub-git-askpass /usr/bin/infrahub-git-askpass
COPY --from=registry.opsmill.io/opsmill/infrahub-git-credential-helper:latest /usr/bin/infrahub-git-credential /usr/bin/infrahub-git-credential
COPY --from=registry.opsmill.io/opsmill/infrahub-git-credential-helper:latest /usr/bin/infrahub-git-askpass /usr/bin/infrahub-git-askpass
```

## License
Expand Down