name: Kubectl Apply (in-repo manifests) description: Validate KUBE_CONFIG, install kubectl, and apply Kubernetes manifest(s) that live inside the repository. inputs: kube_config: description: Full kubeconfig YAML content (pass via secrets) required: true manifest: description: Path (relative to repo root) of a single manifest file to apply. Usable alongside `manifests`. required: false default: "" manifests: description: >- Space- or comma-separated list of manifest file paths (relative to repo root) to apply. Each is applied with its own `kubectl apply -f`. required: false default: "" namespace: description: >- Optional namespace override applied with `-n`. Manifests may also declare their own namespace in metadata; this only adds `-n` when non-empty. required: false default: "" kube_version: description: Kubernetes version to download (stable, or a specific version like v1.31.0) required: false default: stable runs: using: composite steps: - name: Check KUBE_CONFIG validity shell: bash env: KUBE_CONFIG: ${{ inputs.kube_config }} run: | if [ -z "${KUBE_CONFIG}" ] || [ "${KUBE_CONFIG// }" = "" ]; then echo "KUBE_CONFIG is not set or is empty." exit 1 fi - name: Check out repository uses: actions/checkout@v4 - name: Download and install kubectl shell: bash env: KUBE_VERSION: ${{ inputs.kube_version }} run: | # strip stray CR (CRLF checkout via core.autocrlf) KUBE_VERSION=$(printf '%s' "${KUBE_VERSION}" | tr -d '\r') # 1. Check if kubectl is already pre-installed and meets version requirements if command -v kubectl &> /dev/null; then INSTALLED_VER=$(kubectl version --client --output=json 2>/dev/null | grep -oE '"gitVersion": "[^"]+"' | cut -d'"' -f4) if [ -z "${INSTALLED_VER}" ]; then INSTALLED_VER=$(kubectl version --client 2>/dev/null | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+') fi echo "Found pre-installed kubectl version: ${INSTALLED_VER}" # If stable or version matches, reuse pre-installed kubectl if [ "${KUBE_VERSION}" = "stable" ] || [ "${INSTALLED_VER}" = "${KUBE_VERSION}" ]; then echo "Using pre-installed kubectl." exit 0 fi fi # 2. Check/install curl if missing if ! command -v curl &> /dev/null; then echo "curl not found, attempting to install..." if command -v apt-get &> /dev/null; then apt-get update -y && apt-get install -y curl elif command -v apk &> /dev/null; then apk add --no-cache curl elif command -v dnf &> /dev/null; then dnf install -y curl elif command -v yum &> /dev/null; then yum install -y curl else echo "::error::curl is missing and no supported package manager (apt-get, apk, dnf, yum) was found." exit 1 fi fi # 3. Resolve version if [ "${KUBE_VERSION}" = "stable" ]; then KUBE_VER="$(curl -L -s https://dl.k8s.io/release/stable.txt)" else KUBE_VER="${KUBE_VERSION}" fi # 4. Download kubectl echo "Downloading kubectl version ${KUBE_VER}..." curl -LO "https://dl.k8s.io/release/${KUBE_VER}/bin/linux/amd64/kubectl" # 5. Install kubectl to a writable directory if [ -w "/usr/local/bin" ]; then install -m 0755 kubectl /usr/local/bin/kubectl echo "Installed kubectl to /usr/local/bin" else echo "/usr/local/bin is not writable. Installing locally and updating PATH..." LOCAL_BIN="${HOME}/.local/bin" mkdir -p "${LOCAL_BIN}" install -m 0755 kubectl "${LOCAL_BIN}/kubectl" echo "${LOCAL_BIN}" >> "$GITHUB_PATH" export PATH="${LOCAL_BIN}:${PATH}" echo "Installed kubectl to ${LOCAL_BIN}" fi kubectl version --client - name: Set up kubeconfig shell: bash env: KUBE_CONFIG: ${{ inputs.kube_config }} run: | # strip stray CR (CRLF checkout via core.autocrlf) printf '%s' "${KUBE_CONFIG}" | tr -d '\r' > kubeconfig.yaml kubectl --kubeconfig=kubeconfig.yaml cluster-info - name: Apply manifests shell: bash env: MANIFEST: ${{ inputs.manifest }} MANIFESTS: ${{ inputs.manifests }} NAMESPACE: ${{ inputs.namespace }} run: | # strip stray CR (CRLF checkout via core.autocrlf) NAMESPACE=$(printf '%s' "${NAMESPACE}" | tr -d '\r') MANIFEST=$(printf '%s' "${MANIFEST}" | tr -d '\r') MANIFESTS=$(printf '%s' "${MANIFESTS}" | tr -d '\r') NS_FLAG="" if [ -n "${NAMESPACE}" ] && [ "${NAMESPACE// }" != "" ]; then NS_FLAG="-n ${NAMESPACE}" fi # Collect files from both inputs (manifests splits on comma or space). FILES="" if [ -n "${MANIFEST}" ] && [ "${MANIFEST// }" != "" ]; then FILES="${FILES} ${MANIFEST}" fi if [ -n "${MANIFESTS}" ] && [ "${MANIFESTS// }" != "" ]; then for f in $(echo "${MANIFESTS}" | tr ',' ' '); do FILES="${FILES} ${f}" done fi if [ -z "${FILES// }" ]; then echo "::error::No manifest provided. Set the \`manifest\` or \`manifests\` input." exit 1 fi for f in ${FILES}; do if [ ! -f "${f}" ]; then echo "::error::Manifest not found in repo: ${f}" exit 1 fi echo "== applying ${f} ==" kubectl --kubeconfig=kubeconfig.yaml apply -f "${f}" ${NS_FLAG} done