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
2 changes: 1 addition & 1 deletion .github/workflows/cross-arch-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: macos-13 # Intel
- os: macos-15-intel # Intel
arch: amd64
binary: kubectl-oadp_${{ needs.build-all.outputs.suffix }}darwin_amd64
- os: macos-latest # Apple Silicon
Expand Down
116 changes: 9 additions & 107 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,126 +33,28 @@ jobs:
go mod verify
echo "Dependencies ready"

- name: Build all architectures
- name: Build release archives with checksums
run: |
set -e
echo "Building all architectures for release ${{ github.ref_name }}..."
if ! make release-build VERSION="${{ github.ref_name }}"; then
echo "❌ Build failed"
echo "Building release binaries and archives for ${{ github.ref_name }}..."
if ! make release-archives VERSION="${{ github.ref_name }}"; then
echo "❌ Build or archive creation failed"
exit 1
fi
echo "✅ All builds completed"
echo "✅ All builds and archives completed"

- name: Create release archives
run: |
set -e
echo "Creating release archives..."

# Define the platforms we want for krew (must match oadp.yaml)
declare -a platforms=(
"linux_amd64"
"linux_arm64"
"linux_ppc64le"
"linux_s390x"
"darwin_amd64"
"darwin_arm64"
"windows_amd64"
"windows_arm64"
)

# Create archives only for krew platforms
for platform in "${platforms[@]}"; do
if [[ "$platform" == *"windows"* ]]; then
# Windows binaries have .exe extension
binary="kubectl-oadp_${{ github.ref_name }}_${platform}.exe"
if [[ -f "$binary" ]]; then
echo "Creating archive for $platform..."
cp "$binary" kubectl-oadp.exe
tar -czf "kubectl-oadp_${{ github.ref_name }}_${platform}.tar.gz" kubectl-oadp.exe LICENSE
rm kubectl-oadp.exe
echo "✅ Created kubectl-oadp_${{ github.ref_name }}_${platform}.tar.gz"
else
echo "❌ Binary not found: $binary"
exit 1
fi
else
# Unix binaries (no extension)
binary="kubectl-oadp_${{ github.ref_name }}_${platform}"
if [[ -f "$binary" ]]; then
echo "Creating archive for $platform..."
cp "$binary" kubectl-oadp
tar -czf "kubectl-oadp_${{ github.ref_name }}_${platform}.tar.gz" kubectl-oadp LICENSE
rm kubectl-oadp
echo "✅ Created kubectl-oadp_${{ github.ref_name }}_${platform}.tar.gz"
else
echo "❌ Binary not found: $binary"
exit 1
fi
fi
done

echo ""
echo "Release archives created:"
ls -la *.tar.gz

- name: Generate SHA256 checksums
run: |
set -e
echo "Generating SHA256 checksums..."
sha256sum *.tar.gz > checksums.txt
# Create consolidated checksums file for release
cat *.tar.gz.sha256 > checksums.txt
echo ""
echo "Checksums:"
cat checksums.txt

- name: Generate final krew manifest
run: |
set -e
echo "Generating final krew manifest with version ${{ github.ref_name }}..."

# Set environment variables for template substitution
export VERSION="${{ github.ref_name }}"
export LINUX_AMD64_SHA=$(grep "kubectl-oadp_${{ github.ref_name }}_linux_amd64.tar.gz" checksums.txt | cut -d' ' -f1)
export LINUX_ARM64_SHA=$(grep "kubectl-oadp_${{ github.ref_name }}_linux_arm64.tar.gz" checksums.txt | cut -d' ' -f1)
export DARWIN_AMD64_SHA=$(grep "kubectl-oadp_${{ github.ref_name }}_darwin_amd64.tar.gz" checksums.txt | cut -d' ' -f1)
export DARWIN_ARM64_SHA=$(grep "kubectl-oadp_${{ github.ref_name }}_darwin_arm64.tar.gz" checksums.txt | cut -d' ' -f1)
export WINDOWS_AMD64_SHA=$(grep "kubectl-oadp_${{ github.ref_name }}_windows_amd64.tar.gz" checksums.txt | cut -d' ' -f1)
export WINDOWS_ARM64_SHA=$(grep "kubectl-oadp_${{ github.ref_name }}_windows_arm64.tar.gz" checksums.txt | cut -d' ' -f1)

# Validate all checksums were found
if [[ -z "$LINUX_AMD64_SHA" || -z "$LINUX_ARM64_SHA" || -z "$DARWIN_AMD64_SHA" || -z "$DARWIN_ARM64_SHA" || -z "$WINDOWS_AMD64_SHA" || -z "$WINDOWS_ARM64_SHA" ]]; then
echo "❌ Some checksums are missing!"
echo "Available checksums:"
cat checksums.txt
exit 1
fi

# Use envsubst to substitute environment variables in template
# Save original template and generate final manifest
cp oadp.yaml oadp-template.yaml
envsubst < oadp-template.yaml > oadp.yaml

echo "✅ Final krew manifest generated successfully!"
echo ""
echo "Summary:"
echo "Version: $VERSION"
echo "Linux amd64: ${LINUX_AMD64_SHA:0:16}..."
echo "Linux arm64: ${LINUX_ARM64_SHA:0:16}..."
echo "Darwin amd64: ${DARWIN_AMD64_SHA:0:16}..."
echo "Darwin arm64: ${DARWIN_ARM64_SHA:0:16}..."
echo "Windows amd64: ${WINDOWS_AMD64_SHA:0:16}..."
echo "Windows arm64: ${WINDOWS_ARM64_SHA:0:16}..."

echo ""
echo "Final manifest preview:"
grep -E "(version:|sha256:)" oadp.yaml

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
*.tar.gz
checksums.txt
oadp.yaml
body: |
## OADP CLI ${{ github.ref_name }}

Expand Down Expand Up @@ -185,10 +87,10 @@ jobs:
### Files Included
- **Binary archives**: Platform-specific kubectl-oadp binaries with LICENSE
- **checksums.txt**: SHA256 checksums for all binaries
- **oadp.yaml**: Final krew plugin manifest with populated SHA256 values (ready for krew index)

### For Krew Index Maintainers
The `oadp.yaml` file contains the complete krew plugin manifest with all SHA256 checksums populated and can be used directly for krew index submissions.
- On creating new releases, krew-release-bot will automatically open a PR to the krew index with the new release
- Must be non-prerelease semver tag
draft: false
prerelease: false
env:
Expand Down
77 changes: 49 additions & 28 deletions COMPLETION.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,51 +75,61 @@ Create the wrapper script in the same directory as your `kubectl-oadp` binary:
#### For kubectl plugin completion:

```bash
# If kubectl-oadp is in ~/.local/bin (most common)
cat > ~/.local/bin/kubectl_complete-oadp << 'EOF'
# Auto-detect kubectl-oadp location and create wrapper
OADP_PATH=$(which kubectl-oadp)
OADP_DIR=$(dirname "$OADP_PATH")

cat > "${OADP_DIR}/kubectl_complete-oadp" << EOF
#!/bin/bash
# Wrapper script for kubectl plugin completion
exec ~/.local/bin/kubectl-oadp __complete "$@"
exec ${OADP_PATH} __complete "\$@"
EOF
chmod +x ~/.local/bin/kubectl_complete-oadp
chmod +x "${OADP_DIR}/kubectl_complete-oadp"
```

#### For oc plugin completion:

If you also want `oc oadp` completion (using the same binary as an oc plugin):

```bash
# Create oc completion wrapper
cat > ~/.local/bin/oc_complete-oadp << 'EOF'
# Create oc completion wrapper (uses same auto-detected path)
OADP_PATH=$(which kubectl-oadp)
OADP_DIR=$(dirname "$OADP_PATH")

cat > "${OADP_DIR}/oc_complete-oadp" << EOF
#!/bin/bash
# Wrapper script for oc plugin completion
exec ~/.local/bin/kubectl-oadp __complete "$@"
exec ${OADP_PATH} __complete "\$@"
EOF
chmod +x ~/.local/bin/oc_complete-oadp
chmod +x "${OADP_DIR}/oc_complete-oadp"
```

**For other locations:**
- If using `~/bin`: Replace `~/.local/bin` with `~/bin`
- If using `/usr/local/bin`: Replace `~/.local/bin` with `/usr/local/bin`

### 2. Configure Your Shell

Add completion configuration to your shell's rc file:

**For zsh** (add to `~/.zshrc`):
```bash
# kubectl-oadp completion
if [ -f "$HOME/.local/bin/kubectl-oadp" ]; then
source <($HOME/.local/bin/kubectl-oadp completion zsh)
if command -v kubectl-oadp >/dev/null 2>&1; then
source <(kubectl-oadp completion zsh)
compdef _oadp kubectl-oadp
fi
```

**For bash** (add to `~/.bashrc`):
```bash
# kubectl-oadp completion
if [ -f "$HOME/.local/bin/kubectl-oadp" ]; then
source <($HOME/.local/bin/kubectl-oadp completion bash)
if command -v kubectl-oadp >/dev/null 2>&1; then
source <(kubectl-oadp completion bash)
fi
```

**Note for minimal environments (containers, etc.):** If you get `_get_comp_words_by_ref: command not found` errors, the bash-completion framework needs to be loaded first. Add this before the kubectl-oadp completion:
```bash
# Load bash-completion framework (if not auto-loaded)
if [ -f /usr/share/bash-completion/bash_completion ] && ! type _get_comp_words_by_ref >/dev/null 2>&1; then
source /usr/share/bash-completion/bash_completion
fi
```

Expand Down Expand Up @@ -157,12 +167,14 @@ You should see available commands like `backup`, `nonadmin`, `nabsl`, etc.

**Check if wrapper exists:**
```bash
ls -la ~/.local/bin/kubectl_complete-oadp
# Find where kubectl-oadp is installed
OADP_DIR=$(dirname $(which kubectl-oadp))
ls -la "${OADP_DIR}/kubectl_complete-oadp"
```

**Check if it's executable:**
```bash
chmod +x ~/.local/bin/kubectl_complete-oadp
chmod +x "${OADP_DIR}/kubectl_complete-oadp"
```

**Test wrapper directly:**
Expand All @@ -176,28 +188,30 @@ kubectl_complete-oadp __complete kubectl oadp
grep -A5 "kubectl-oadp completion" ~/.zshrc

# For bash
grep -A3 "kubectl-oadp completion" ~/.bashrc
grep -A5 "kubectl-oadp completion" ~/.bashrc
```

### Path Issues?

Make sure both files are in the same directory and that directory is in your PATH:
```bash
echo $PATH | grep -o '[^:]*\.local/bin[^:]*'
which kubectl-oadp
which kubectl_complete-oadp
which oc_complete-oadp # if using oc completion

# Check if the directory is in PATH
OADP_DIR=$(dirname $(which kubectl-oadp))
echo $PATH | grep -q "$OADP_DIR" && echo "✓ In PATH" || echo "✗ Not in PATH"
```

## Uninstalling Completion

### Remove the Wrapper Scripts
```bash
# Remove kubectl completion wrapper
rm ~/.local/bin/kubectl_complete-oadp

# Remove oc completion wrapper (if created)
rm ~/.local/bin/oc_complete-oadp
# Find and remove the wrapper scripts
OADP_DIR=$(dirname $(which kubectl-oadp))
rm "${OADP_DIR}/kubectl_complete-oadp"
rm "${OADP_DIR}/oc_complete-oadp" # if you created this
```

### Remove Shell Configuration
Expand All @@ -214,19 +228,26 @@ rm ~/.local/bin/oc_complete-oadp

## Advanced: Custom Locations

If your `kubectl-oadp` binary is in a non-standard location, update the wrapper script paths:
If your `kubectl-oadp` binary is in a non-standard location, the dynamic detection will automatically handle it as long as the binary is in your `$PATH`. If it's not in your PATH, you can either:

1. **Add it to PATH** (recommended):
```bash
export PATH="/opt/oadp/bin:$PATH"
# Then use the standard setup commands above
```

2. **Use explicit paths**:
```bash
# Example for custom location /opt/oadp/bin
cat > /opt/oadp/bin/kubectl_complete-oadp << 'EOF'
#!/bin/bash
exec /opt/oadp/bin/kubectl-oadp __complete "$@"
EOF
chmod +x /opt/oadp/bin/kubectl_complete-oadp

# Update shell config accordingly
if [ -f "/opt/oadp/bin/kubectl-oadp" ]; then
source <(/opt/oadp/bin/kubectl-oadp completion zsh)
compdef _oadp kubectl-oadp
source </(/opt/oadp/bin/kubectl-oadp completion bash)
fi
```

Expand Down
11 changes: 2 additions & 9 deletions Containerfile.download
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,11 @@ RUN go mod download && go mod verify

COPY . .

# Build ALL kubectl-oadp binaries using native Go cross-compilation (no QEMU emulation)
# The download server needs to serve binaries for all platforms, not just one arch
RUN make release-build && \
RUN make release-archives && \
mkdir -p /archives && \
for binary in kubectl-oadp_*; do \
archive_name=$(echo "$binary" | sed 's/\.exe$//' ).tar.gz; \
tar -czf "/archives/$archive_name" "$binary"; \
echo "Created /archives/$archive_name"; \
done
mv *.tar.gz /archives/

# Build the download server for the TARGET platform (the arch this container will run on)
# This uses cross-compilation so the builder can run natively on amd64
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o download-server ./cmd/downloads/server.go

# Clean up to reduce layer size
Expand Down
Loading
Loading