Skip to content
Open
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
58 changes: 58 additions & 0 deletions .github/actions/build-and-sign-image/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: 'Build and Sign Container Image'
description: 'Build Docker image, push to registry, and sign with Cosign'

inputs:
image-name:
description: 'Full image name with tag (registry/repo:tag)'
required: true
dockerfile:
description: 'Path to Dockerfile'
required: false
default: './Dockerfile'
context:
description: 'Build context path'
required: false
default: '.'
sign-image:
description: 'Sign image with cosign'
required: false
default: 'true'
cosign-private-key:
description: 'Cosign private key'
required: false
cosign-password:
description: 'Cosign password'
required: false
build-args:
description: 'Additional build arguments'
required: false
default: ''

runs:
using: 'composite'
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and Push Image
shell: bash
run: |
make docker-buildx IMG=${{ inputs.image-name }} ${{ inputs.build-args }}
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

The make docker-buildx command is called with build-args concatenated directly. If inputs.build-args is empty, this works fine, but if it contains special characters or spaces, it could cause issues. Consider using proper shell quoting or conditional inclusion.

Example:

if [ -n "${{ inputs.build-args }}" ]; then
  make docker-buildx IMG=${{ inputs.image-name }} BUILD_ARGS="${{ inputs.build-args }}"
else
  make docker-buildx IMG=${{ inputs.image-name }}
fi
Suggested change
make docker-buildx IMG=${{ inputs.image-name }} ${{ inputs.build-args }}
if [ -n "${{ inputs.build-args }}" ]; then
make docker-buildx IMG="${{ inputs.image-name }}" BUILD_ARGS="${{ inputs.build-args }}"
else
make docker-buildx IMG="${{ inputs.image-name }}"
fi

Copilot uses AI. Check for mistakes.

- name: Set up Cosign
if: inputs.sign-image == 'true'
uses: sigstore/cosign-installer@main
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

Using @main for the sigstore/cosign-installer action is not recommended for production workflows as it can introduce breaking changes without notice. Pin to a specific version or use a commit SHA for stability and security.

Example:

uses: sigstore/[email protected]
Suggested change
uses: sigstore/cosign-installer@main
uses: sigstore/cosign-installer@v3.5.0

Copilot uses AI. Check for mistakes.

- name: Sign Image with Cosign
if: inputs.sign-image == 'true'
shell: bash
run: |
cosign sign --yes --key env://COSIGN_PRIVATE_KEY ${{ inputs.image-name }}
env:
COSIGN_PRIVATE_KEY: ${{ inputs.cosign-private-key }}
COSIGN_PASSWORD: ${{ inputs.cosign-password }}

outputs:
image-digest:
description: 'Image digest SHA'
value: ${{ steps.build.outputs.digest }}
Comment on lines +55 to +58
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

The outputs section is defined but there's no step with id: build that sets the digest output. The build step doesn't have an id, so ${{ steps.build.outputs.digest }} will always be empty. Either add an id: build to the "Build and Push Image" step and ensure it outputs the digest, or remove the unused outputs section.

Copilot uses AI. Check for mistakes.
40 changes: 40 additions & 0 deletions .github/actions/collect-test-artifacts/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: 'Collect Test Artifacts'
description: 'Collect and upload pod logs and test artifacts'

inputs:
artifact-name:
description: 'Name for the artifact'
required: true
log-path:
description: 'Path to collect logs from'
required: false
default: './test'
additional-paths:
description: 'Additional paths to collect (newline separated)'
required: false
default: ''

runs:
using: 'composite'
steps:
- name: Collect Test Logs
if: always()
shell: bash
run: |
mkdir -p /tmp/pod_logs
find ${{ inputs.log-path }} -name "*.log" -exec cp {} /tmp/pod_logs \; 2>/dev/null || true

# Collect additional paths if specified
if [ -n "${{ inputs.additional-paths }}" ]; then
while IFS= read -r path; do
[ -n "$path" ] && cp -r "$path" /tmp/pod_logs/ 2>/dev/null || true
done <<< "${{ inputs.additional-paths }}"
fi

- name: Archive Artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact-name }}
path: /tmp/pod_logs/**
retention-days: 7
53 changes: 53 additions & 0 deletions .github/actions/configure-cloud-auth/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: 'Configure Cloud Provider Authentication'
description: 'Setup authentication for AWS, Azure, or GCP'

inputs:
cloud-provider:
description: 'Cloud provider: aws, azure, or gcp'
required: true
aws-access-key-id:
description: 'AWS Access Key ID'
required: false
aws-secret-access-key:
description: 'AWS Secret Access Key'
required: false
aws-region:
description: 'AWS Region'
required: false
azure-credentials:
description: 'Azure credentials JSON'
required: false
gcp-service-account-key:
description: 'GCP service account key JSON'
required: false

runs:
using: 'composite'
steps:
- name: Configure AWS credentials
if: inputs.cloud-provider == 'aws'
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ inputs.aws-access-key-id }}
aws-secret-access-key: ${{ inputs.aws-secret-access-key }}
aws-region: ${{ inputs.aws-region }}

- name: Login to Amazon ECR
if: inputs.cloud-provider == 'aws'
uses: aws-actions/amazon-ecr-login@v2

- name: Azure Login
if: inputs.cloud-provider == 'azure'
uses: azure/login@v2
with:
creds: ${{ inputs.azure-credentials }}

- name: GCP Authentication
if: inputs.cloud-provider == 'gcp'
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ inputs.gcp-service-account-key }}

- name: Setup gcloud
if: inputs.cloud-provider == 'gcp'
uses: google-github-actions/setup-gcloud@v2
62 changes: 62 additions & 0 deletions .github/actions/setup-k8s-tools/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: 'Setup Kubernetes Tools'
description: 'Install kubectl, helm, eksctl, and other Kubernetes tools'

inputs:
kubectl-version:
description: 'Kubectl version'
required: true
helm-version:
description: 'Helm version'
required: false
default: 'v3.8.2'
eksctl-version:
description: 'eksctl version'
required: false
install-metrics-server:
description: 'Install metrics server'
required: false
default: 'false'

runs:
using: 'composite'
steps:
- name: Install Kubectl
uses: Azure/setup-kubectl@v4
with:
version: ${{ inputs.kubectl-version }}

- name: Install Helm
shell: bash
run: |
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
DESIRED_VERSION=${{ inputs.helm-version }} bash get_helm.sh
helm version

- name: Install EKS CLI
if: inputs.eksctl-version != ''
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

The condition if: inputs.eksctl-version != '' checks for a non-empty string, but in YAML an unset value is null, not an empty string. This condition should be if: inputs.eksctl-version to properly handle both null and empty string cases.

Suggested change
if: inputs.eksctl-version != ''
if: inputs.eksctl-version

Copilot uses AI. Check for mistakes.
shell: bash
run: |
curl --silent --insecure --location "https://github.com/weaveworks/eksctl/releases/download/${{ inputs.eksctl-version }}/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

The insecure flag --insecure is used when downloading eksctl. This disables certificate verification and could allow man-in-the-middle attacks. Remove the --insecure flag to ensure secure downloads.

Change:

curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/${{ inputs.eksctl-version }}/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
Suggested change
curl --silent --insecure --location "https://github.com/weaveworks/eksctl/releases/download/${{ inputs.eksctl-version }}/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/${{ inputs.eksctl-version }}/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp

Copilot uses AI. Check for mistakes.
sudo mv /tmp/eksctl /usr/local/bin
eksctl version

- name: Install Metrics Server
if: inputs.install-metrics-server == 'true'
shell: bash
run: |
curl -LO https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl replace --force -f components.yaml || kubectl apply -f components.yaml

- name: Install Kubernetes Dashboard
if: inputs.install-metrics-server == 'true'
shell: bash
run: |
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.5/aio/deploy/recommended.yaml

- name: Setup Kustomize
shell: bash
run: |
sudo snap install kustomize
mkdir -p ./bin
cp /snap/bin/kustomize ./bin/kustomize
36 changes: 36 additions & 0 deletions .github/actions/setup-operator-tools/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: 'Setup Operator Development Tools'
description: 'Install Operator SDK, Ginkgo, and other operator development tools'

inputs:
operator-sdk-version:
description: 'Operator SDK version to install'
required: true
go-version:
description: 'Go version for setup'
required: true

runs:
using: 'composite'
steps:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ inputs.go-version }}
cache: false

- name: Install Operator SDK
shell: bash
run: |
export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

[nitpick] The script uses inline shell evaluation with $(case ...) which can be fragile. While functional, this could be simplified for better readability:

ARCH=$(uname -m)
case $ARCH in
  x86_64) ARCH=amd64 ;;
  aarch64) ARCH=arm64 ;;
esac
export ARCH
export OS=$(uname | awk '{print tolower($0)}')
Suggested change
export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)
ARCH=$(uname -m)
case "$ARCH" in
x86_64) ARCH=amd64 ;;
aarch64) ARCH=arm64 ;;
esac
export ARCH

Copilot uses AI. Check for mistakes.
export OS=$(uname | awk '{print tolower($0)}')
export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/download/${{ inputs.operator-sdk-version }}
sudo curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH}
sudo chmod +x operator-sdk_${OS}_${ARCH}
sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk
operator-sdk version

- name: Install Ginkgo
shell: bash
run: |
make setup/ginkgo
go mod tidy
Loading
Loading