Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
6e3ddb5
feat: golang src
nimish-ks Feb 8, 2026
6e3c262
feat: add CI workflows for Go project
nimish-ks Feb 8, 2026
d18034c
feat: add .dockerignore file
nimish-ks Feb 8, 2026
869b8c8
feat: refactor Dockerfile for Go application build
nimish-ks Feb 8, 2026
c45c072
feat: implement MCP server and client configuration management
nimish-ks Feb 8, 2026
6e094df
chore: move secret generation to the sdk
nimish-ks Feb 9, 2026
4b7d129
chore: remove tag matches, moved to the sdk
nimish-ks Feb 9, 2026
ea912fa
fix: imports, added comments to imports
nimish-ks Feb 9, 2026
e36587e
chore: moved to sdk
nimish-ks Feb 9, 2026
a3b68b1
chore: moved secret referencing logitc to sdk
nimish-ks Feb 9, 2026
3620f91
chore: moved netcode to sdk
nimish-ks Feb 9, 2026
adf5553
chore: updated imports, fixed references
nimish-ks Feb 9, 2026
506d794
fix: network imports
nimish-ks Feb 9, 2026
1533cfd
chore: removed tag noramalize utisl
nimish-ks Feb 9, 2026
73f6920
chore: refactor ParseEnvFile to use sdk.KeyValuePair
nimish-ks Feb 10, 2026
162675f
feat: add version package with CLI version 2.0.0
nimish-ks Feb 10, 2026
1e96c51
chore: remove CleanSubprocessEnv function from misc.go
nimish-ks Feb 10, 2026
0890788
refactor: simplify GetShellCommand by removing shellMap and directly …
nimish-ks Feb 10, 2026
9de4aa3
refactor: update Phase struct to use sdk.Phase and simplify NewPhase,…
nimish-ks Feb 10, 2026
47e5257
refactor: update secret handling functions to use sdk options and imp…
nimish-ks Feb 10, 2026
592c070
chore: update imports and references
nimish-ks Feb 10, 2026
145eee4
chore: update root command version reference to use version package
nimish-ks Feb 10, 2026
2fe3150
refactor: remove unnecessary environment variable handling in update …
nimish-ks Feb 10, 2026
787e646
refactor: update run and shell commands to utilize sdk options and st…
nimish-ks Feb 10, 2026
6cc301c
refactor: streamline secrets import by utilizing sdk.CreateOptions an…
nimish-ks Feb 10, 2026
3ad7309
refactor: enhance authentication flow by consolidating user data extr…
nimish-ks Feb 10, 2026
bcee56e
refactor: improve authentication process by consolidating user data h…
nimish-ks Feb 10, 2026
bce2ba5
refactor: further streamline authentication process by enhancing user…
nimish-ks Feb 10, 2026
2f4c4d7
chore: update MCP command description to indicate BETA status
nimish-ks Feb 10, 2026
b046bd7
refactor: enhance Dockerfile to support dynamic versioning and archit…
nimish-ks Feb 10, 2026
1167d65
refactor: simplify shell command execution by removing redundant nil …
nimish-ks Feb 10, 2026
cba4d38
test: add unit tests for command execution and configuration parsing
nimish-ks Feb 10, 2026
fa8859a
refactor: remove MCP logic (moved to feat--mcp branch)
nimish-ks Feb 25, 2026
40f2f81
chore: remove mcp deps
nimish-ks Feb 28, 2026
9bd8f53
feat: improved error handling
nimish-ks Feb 28, 2026
51db270
feat: correctly pass paths and improve error handling
nimish-ks Feb 28, 2026
4d1edf1
feat: pass the correct path, sorts the secrets being returned, dont l…
nimish-ks Feb 28, 2026
03f6025
fix: emoji table alignment, restore run injection stats, and improve …
nimish-ks Mar 1, 2026
539fa48
chore: updated readme
nimish-ks Mar 1, 2026
ced1b78
fix: update export tests to use []KeyValue instead of map[string]string
nimish-ks Mar 1, 2026
314cf7e
chore: update readme
nimish-ks Mar 1, 2026
71b6ff6
feat: updated install scrip
nimish-ks Mar 2, 2026
0eaaad7
fix: secret resolution now happens in the sdk
nimish-ks Mar 2, 2026
63c730a
feat: cross compile cli for n targets
nimish-ks Mar 2, 2026
73e57ec
ci: consolidate CI pipeline, add FPM packaging, and enhance install.sh
nimish-ks Mar 2, 2026
b8ed09d
feat: add back base64, base64url
nimish-ks Mar 2, 2026
9764ef3
feat: add CLI host validation
nimish-ks Mar 2, 2026
d67cc99
fix: dynamic secrets path
nimish-ks Mar 2, 2026
c563313
feat: add tests for host url validation
nimish-ks Mar 2, 2026
a7b6073
feat: add the ability to export specific keys
nimish-ks Mar 2, 2026
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
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.git
.venv
.github
__pycache__
*.pyc
media
tests
2-0-TODO.md
*.egg-info
dist
build
.mypy_cache
.pytest_cache
20 changes: 13 additions & 7 deletions .github/workflows/attach-to-release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Attach Assets to Release
name: "Attach Assets to Release"

on:
workflow_call:
Expand All @@ -10,17 +10,23 @@ on:
jobs:
attach-to-release:
name: Attach Assets to Release
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Download processed assets
- name: Download binaries
uses: actions/download-artifact@v4
with:
name: phase-cli-release
path: ./phase-cli-release
name: phase-cli-binaries
path: ./release

- name: Download packages
uses: actions/download-artifact@v4
with:
name: phase-cli-packages
path: ./release

- name: Attach assets to release
uses: softprops/action-gh-release@v2
with:
files: ./phase-cli-release/*
files: ./release/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
244 changes: 21 additions & 223 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,245 +1,43 @@
name: Build CLI
name: "Cross-compile"

on:
workflow_call:
inputs:
version:
required: true
type: string
python_version:
required: true
type: string
alpine_version:
required: true
type: string

jobs:
build:
name: Build CLI
runs-on: ${{ matrix.os }}
strategy:
matrix:
# ubuntu-22.04 - context: https://github.com/phasehq/cli/issues/94
# macos-15-intel darwin-amd64 builds (intel)
# macos-14 darwin-arm64 builds (apple silicon)
# context: https://github.com/actions/runner-images?tab=readme-ov-file#available-images

os: [ubuntu-22.04, windows-2022, macos-15-intel, macos-14]
name: Cross-compile all targets
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python_version }}
- run: pip install -r requirements.txt
if: runner.os != 'Linux'
- run: pip install pyinstaller==6.16.0
if: runner.os != 'Linux'
- run: pyinstaller --hidden-import _cffi_backend --paths ./phase_cli --name phase phase_cli/main.py
if: runner.os != 'Linux'
- name: Build Linux binary in manylinux_2_28 container (glibc 2.28 baseline)
if: matrix.os == 'ubuntu-22.04'
# Design decisions:
# - Use manylinux_2_28 for Linux builds to target glibc 2.28 baseline while maintaining wide compatibility
# - Build CPython in-container with --enable-shared (shared libpython) so PyInstaller can bundle correctly.
# - Use system OpenSSL from manylinux_2_28; avoid building OpenSSL from source for speed and simplicity.
# - Install Python from source with --enable-shared to ensure a shared libpython is available for PyInstaller.
# - Package PyInstaller onedir under /usr/lib/phase and symlink /usr/bin/phase to preserve metadata and bundled files (avoids runtime import errors on RPM-based distros).
# - Print ldd --version
run: |
docker run --rm \
-v "${PWD}":/workspace \
-w /workspace \
quay.io/pypa/manylinux_2_28_x86_64 \
/bin/bash -lc 'set -euo pipefail; \
echo "=== ldd version (manylinux_2_28 x86_64) ==="; \
ldd --version; \
echo "=== Installing build deps ==="; \
yum -y install wget tar make gcc openssl-devel bzip2-devel libffi-devel zlib-devel >/dev/null; \
echo "Install Python from source with --enable-shared to ensure a shared libpython is available for PyInstaller."; \
echo "=== Building Python ${{ inputs.python_version }} with --enable-shared ==="; \
PYVER="${{ inputs.python_version }}"; \
MAJOR=$(echo "$PYVER" | cut -d. -f1); \
MINOR=$(echo "$PYVER" | cut -d. -f2); \
FULLVER=$(curl -s https://www.python.org/ftp/python/ | grep -oE ">${MAJOR}\\.${MINOR}\\.[0-9]+/" | tr -d ">/" | sort -V | tail -1 || echo "$PYVER"); \
cd /tmp; \
wget -q https://www.python.org/ftp/python/${FULLVER}/Python-${FULLVER}.tgz; \
tar -xzf Python-${FULLVER}.tgz; \
cd Python-${FULLVER}; \
./configure --prefix=/opt/py-shared --enable-shared --with-system-openssl >/dev/null; \
make -j$(nproc) >/dev/null; \
make install >/dev/null; \
export LD_LIBRARY_PATH=/opt/py-shared/lib:$LD_LIBRARY_PATH; \
/opt/py-shared/bin/python3 --version; \
/opt/py-shared/bin/python3 -c '\''import ssl; print("SSL OK")'\''; \
/opt/py-shared/bin/python3 -m pip install --upgrade pip >/dev/null; \
cd /workspace; \
/opt/py-shared/bin/python3 -m pip install -r requirements.txt >/dev/null; \
/opt/py-shared/bin/python3 -m pip install pyinstaller==6.16.0 >/dev/null; \
/opt/py-shared/bin/python3 -m PyInstaller --hidden-import _cffi_backend --paths ./phase_cli --name phase phase_cli/main.py'
shell: bash

- name: Codesign macOS build output
if: runner.os == 'macOS'
run: |
uname -a
codesign --force --deep --sign - dist/phase/phase
codesign --verify --deep --verbose=2 dist/phase/phase
- name: Print GLIBC version
if: matrix.os == 'ubuntu-22.04'
run: ldd --version

# Set LC_ALL based on the runner OS for Linux and macOS
- name: Set LC_ALL for Linux and macOS
run: export LC_ALL=C.UTF-8
if: runner.os != 'Windows'
shell: bash

# Set LC_ALL for Windows
- name: Set LC_ALL for Windows
run: echo "LC_ALL=C.UTF-8" | Out-File -Append -Encoding utf8 $env:GITHUB_ENV
if: runner.os == 'Windows'
shell: pwsh

# Build DEB and RPM packages for Linux
- run: |
sudo apt-get update
sudo apt-get install -y ruby-dev rubygems build-essential
sudo gem install --no-document fpm
# Stage files to preserve PyInstaller onedir layout
rm -rf pkgroot
mkdir -p pkgroot/usr/lib/phase
cp -a dist/phase/. pkgroot/usr/lib/phase/
mkdir -p pkgroot/usr/bin
echo "Symlink ensures PATH-discoverable binary while keeping full onedir intact"
# This will create a symlink to the phase binary in the /usr/lib/phase/ directory
ln -sf ../lib/phase/phase pkgroot/usr/bin/phase
# Build packages from staged root
fpm -s dir -t deb -n phase -v ${{ inputs.version }} -C pkgroot .
fpm -s dir -t rpm -n phase -v ${{ inputs.version }} -C pkgroot .
if: matrix.os == 'ubuntu-22.04'
shell: bash

# Upload DEB and RPM packages
- uses: actions/upload-artifact@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
name: phase-deb
path: "*.deb"
if: matrix.os == 'ubuntu-22.04'
- uses: actions/upload-artifact@v4
with:
name: phase-rpm
path: "*.rpm"
if: matrix.os == 'ubuntu-22.04'

- name: Set artifact name
run: |
if [[ "${{ matrix.os }}" == "macos-14" ]]; then
echo "ARTIFACT_NAME=${{ runner.os }}-arm64-binary" >> $GITHUB_ENV
elif [[ "${{ matrix.os }}" == "macos-15-intel" ]]; then
echo "ARTIFACT_NAME=${{ runner.os }}-amd64-binary" >> $GITHUB_ENV
else
echo "ARTIFACT_NAME=${{ runner.os }}-binary" >> $GITHUB_ENV
fi
shell: bash
go-version: "1.24"
cache-dependency-path: src/go.sum

- name: Upload binary
uses: actions/upload-artifact@v4
- name: Clone Go SDK
uses: actions/checkout@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: dist/phase*
repository: phasehq/golang-sdk
path: golang-sdk

build_arm:
name: Build Linux ARM64
runs-on: ubuntu-22.04-arm
steps:
- uses: actions/checkout@v4
- name: Build with PyInstaller (manylinux_2_28 aarch64 via docker)
run: |
docker run --rm \
-v "${PWD}":/workspace \
-w /workspace \
quay.io/pypa/manylinux_2_28_aarch64 \
/bin/bash -lc 'set -euo pipefail; \
echo "=== ldd version (manylinux_2_28 aarch64) ==="; \
ldd --version; \
echo "=== Installing build deps ==="; \
yum -y install wget tar make gcc openssl-devel bzip2-devel libffi-devel zlib-devel >/dev/null; \
echo "Install Python from source with --enable-shared to ensure a shared libpython is available for PyInstaller."; \
echo "=== Building Python ${{ inputs.python_version }} with --enable-shared ==="; \
PYVER="${{ inputs.python_version }}"; \
MAJOR=$(echo "$PYVER" | cut -d. -f1); \
MINOR=$(echo "$PYVER" | cut -d. -f2); \
FULLVER=$(curl -s https://www.python.org/ftp/python/ | grep -oE ">${MAJOR}\\.${MINOR}\\.[0-9]+/" | tr -d ">/" | sort -V | tail -1 || echo "$PYVER"); \
cd /tmp; \
wget -q https://www.python.org/ftp/python/${FULLVER}/Python-${FULLVER}.tgz; \
tar -xzf Python-${FULLVER}.tgz; \
cd Python-${FULLVER}; \
./configure --prefix=/opt/py-shared --enable-shared --with-system-openssl >/dev/null; \
make -j$(nproc) >/dev/null; \
make install >/dev/null; \
export LD_LIBRARY_PATH=/opt/py-shared/lib:$LD_LIBRARY_PATH; \
/opt/py-shared/bin/python3 --version; \
/opt/py-shared/bin/python3 -c '\''import ssl; print("SSL OK")'\''; \
/opt/py-shared/bin/python3 -m pip install --upgrade pip >/dev/null; \
cd /workspace; \
/opt/py-shared/bin/python3 -m pip install -r requirements.txt >/dev/null; \
/opt/py-shared/bin/python3 -m pip install pyinstaller==6.16.0 >/dev/null; \
/opt/py-shared/bin/python3 -m PyInstaller --hidden-import _cffi_backend --paths ./phase_cli --name phase phase_cli/main.py'
- uses: actions/upload-artifact@v4
with:
name: Linux-binary-arm64
path: dist/phase*
- name: Patch go.mod replace directive for CI
working-directory: src
run: go mod edit -replace github.com/phasehq/golang-sdk=../golang-sdk

build_apk:
name: Build Alpine
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- { os: ubuntu-22.04, arch: x86_64 }
- { os: ubuntu-22.04-arm, arch: aarch64 }
steps:
- uses: actions/checkout@v4
- name: Build Alpine package
- name: Build all targets
run: |
if [ "${{ matrix.arch }}" = "aarch64" ]; then
TARGET_ARCH="arm64"
elif [ "${{ matrix.arch }}" = "x86_64" ]; then
TARGET_ARCH="amd64"
fi

# CONTEXT: phase_cli_linux_<ARCH>_alpine_<VERSION> artifact will contain phase_cli_linux_<ARCH>_<VERSION>.apk

OUTPUT_PACKAGE_NAME="phase_cli_linux_${TARGET_ARCH}_${{ inputs.version }}.apk"
ARTIFACT_NAME="phase_cli_linux_${TARGET_ARCH}_alpine_${{ inputs.version }}"

echo "OUTPUT_PACKAGE_NAME=$OUTPUT_PACKAGE_NAME" >> $GITHUB_ENV
echo "ARTIFACT_NAME=$ARTIFACT_NAME" >> $GITHUB_ENV
VERSION="${{ inputs.version }}" OUTPUT_DIR=dist \
bash scripts/build.sh

mkdir -p ./output
docker run --rm \
-v "${PWD}":/workspace \
-w /workspace \
--env ABUILD_USER=builder \
--env ARCH=${{ matrix.arch }} \
--env OUTPUT_PACKAGE_NAME="$OUTPUT_PACKAGE_NAME" \
alpine:${{ inputs.alpine_version }} \
/bin/sh -ec " \
set -ex; \
apk update; \
apk add --no-cache alpine-sdk python3 python3-dev py3-pip build-base git curl sudo doas; \
adduser -D builder; \
addgroup builder abuild; \
echo 'builder ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers; \
echo 'permit nopass builder as root' >> /etc/doas.conf; \
chown -R builder /workspace; \
sudo -u builder /bin/sh -ec 'cd /workspace && export HOME=/home/builder && abuild-keygen -a -i -n'; \
sudo -u builder /bin/sh -ec 'cd /workspace && abuild -r'; \
SOURCE_APK=\$(find /home/builder/packages/\$ARCH -name 'phase-*.apk' -print -quit); \
cp \"\$SOURCE_APK\" \"/workspace/output/\$OUTPUT_PACKAGE_NAME\" \
"
- name: Upload APK artifacts
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: ./output/${{ env.OUTPUT_PACKAGE_NAME }}
name: phase-cli-binaries
path: dist/
retention-days: 7
Loading
Loading