Skip to content

bump version to 0.2.0 #11

bump version to 0.2.0

bump version to 0.2.0 #11

Workflow file for this run

name: Release
on:
push:
branches:
- 'release/*' # Only trigger on release branches
workflow_dispatch:
inputs:
tag:
description: 'Tag to release'
required: true
default: 'v0.1.0'
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
permissions:
contents: write
packages: write
jobs:
build:
strategy:
matrix:
include:
# Windows
- target: x86_64-pc-windows-msvc
os: windows-latest
name: httpc-windows-x64
# macOS
- target: x86_64-apple-darwin
os: macos-latest
name: httpc-macos-x64
- target: aarch64-apple-darwin
os: macos-latest
name: httpc-macos-arm64
# Linux
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
name: httpc-linux-x64
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
name: httpc-linux-arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-${{ matrix.target }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-${{ matrix.target }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v4
with:
path: target
key: ${{ runner.os }}-${{ matrix.target }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
- name: Install cross-compilation tools (Linux ARM64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
- name: Configure cross-compilation (Linux ARM64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
mkdir -p ~/.cargo
echo '[target.aarch64-unknown-linux-gnu]' >> ~/.cargo/config.toml
echo 'linker = "aarch64-linux-gnu-gcc"' >> ~/.cargo/config.toml
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }}
- name: Prepare binary (Windows)
if: matrix.os == 'windows-latest'
run: |
cp target/${{ matrix.target }}/release/httpc.exe ${{ matrix.name }}.exe
- name: Prepare binary (Unix)
if: matrix.os != 'windows-latest'
run: |
cp target/${{ matrix.target }}/release/httpc ${{ matrix.name }}
chmod +x ${{ matrix.name }}
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}
path: ${{ matrix.name }}${{ runner.os == 'Windows' && '.exe' || '' }}
if-no-files-found: error
build-packages:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download Linux binary
uses: actions/download-artifact@v4
with:
name: httpc-linux-x64
path: binaries/
- name: Install packaging tools
run: |
sudo apt-get update
sudo apt-get install -y rpm alien fakeroot
- name: Setup package structure
run: |
chmod +x binaries/httpc-linux-x64
# Create directory structure for packaging
mkdir -p packaging/usr/bin
mkdir -p packaging/usr/share/man/man1
mkdir -p packaging/DEBIAN
mkdir -p packaging/usr/share/doc/httpc
mkdir -p packaging/etc/httpc
# Copy binary
cp binaries/httpc-linux-x64 packaging/usr/bin/httpc
# Create profiles template
cat > packaging/etc/httpc/profiles.example << 'EOF'
# httpc Configuration Profiles
# Copy this file to ~/.httpc/profiles and customize as needed
[default]
host = https://api.example.com
@content-type = application/json
@accept = application/json
# user = username
# password = password
# insecure = false
# ca_cert = /path/to/cert.pem
[local]
host = http://localhost:8080
@content-type = application/json
[staging]
host = https://staging-api.example.com
@content-type = application/json
@authorization = Bearer your-token-here
EOF
# Create basic man page
cat > packaging/usr/share/man/man1/httpc.1 << 'EOF'
.TH HTTPC 1 "$(date +'%B %Y')" "httpc $(grep '^version' Cargo.toml | cut -d'"' -f2)" "User Commands"
.SH NAME
httpc \- A flexible HTTP client with profile support
.SH SYNOPSIS
.B httpc
[\fIOPTIONS\fR] \fIMETHOD\fR \fIURL\fR
.SH DESCRIPTION
\fBhttpc\fP is a flexible HTTP client that supports configuration profiles and various authentication methods.
.SH OPTIONS
.TP
\fB\-p, \-\-profile\fR \fIPROFILE\fR
Use the specified profile from ~/.httpc/profiles
.TP
\fB\-H, \-\-header\fR \fIHEADER\fR
Add custom HTTP header
.TP
\fB\-d, \-\-data\fR \fIDATA\fR
Send data in request body
.TP
\fB\-v, \-\-verbose\fR
Enable verbose output
.TP
\fB\-h, \-\-help\fR
Show help message
.TP
\fB\-V, \-\-version\fR
Show version information
.SH CONFIGURATION
Configuration profiles are stored in ~/.httpc/profiles in INI format.
See /etc/httpc/profiles.example for configuration examples.
.SH EXAMPLES
.TP
httpc GET https://api.example.com/users
.TP
httpc -p staging POST /api/data -d '{"key": "value"}'
.TP
httpc -H "Authorization: Bearer token" GET /protected
.SH AUTHOR
Written by Satoshi Iizuka.
.SH REPORTING BUGS
Report bugs to: https://github.com/samwisely75/httpc/issues
EOF
# Compress man page
gzip packaging/usr/share/man/man1/httpc.1
# Create copyright file
cp LICENSE packaging/usr/share/doc/httpc/copyright
# Create changelog
echo "httpc ($(grep '^version' Cargo.toml | cut -d'"' -f2)) stable; urgency=medium" > packaging/usr/share/doc/httpc/changelog.Debian
echo "" >> packaging/usr/share/doc/httpc/changelog.Debian
echo " * Release version $(grep '^version' Cargo.toml | cut -d'"' -f2)" >> packaging/usr/share/doc/httpc/changelog.Debian
echo "" >> packaging/usr/share/doc/httpc/changelog.Debian
echo " -- Satoshi Iizuka <[email protected]> $(date -R)" >> packaging/usr/share/doc/httpc/changelog.Debian
# Compress changelog
gzip packaging/usr/share/doc/httpc/changelog.Debian
- name: Create DEB package
run: |
VERSION=$(grep '^version' Cargo.toml | cut -d'"' -f2)
# Create DEBIAN control file
cat > packaging/DEBIAN/control << EOF
Package: httpc
Version: ${VERSION}
Section: utils
Priority: optional
Architecture: amd64
Depends: libc6 (>= 2.17)
Maintainer: Satoshi Iizuka <[email protected]>
Description: A flexible HTTP client with profile support
httpc is a flexible HTTP client that supports configuration profiles,
various authentication methods, and custom headers. It's designed for
developers who need a powerful command-line HTTP client for testing
APIs and web services.
Homepage: https://github.com/samwisely75/httpc
EOF
# Create postinst script
cat > packaging/DEBIAN/postinst << 'EOF'
#!/bin/bash
set -e
# Create httpc config directory if it doesn't exist
if [ ! -d "/etc/httpc" ]; then
mkdir -p /etc/httpc
fi
# Copy example profiles if user doesn't have profiles yet
if [ ! -f "$HOME/.httpc/profiles" ] && [ -f "/etc/httpc/profiles.example" ]; then
mkdir -p "$HOME/.httpc"
cp /etc/httpc/profiles.example "$HOME/.httpc/profiles"
echo "Created default profiles at $HOME/.httpc/profiles"
echo "Edit this file to configure your API endpoints"
fi
exit 0
EOF
chmod +x packaging/DEBIAN/postinst
# Build DEB package
fakeroot dpkg-deb --build packaging httpc_${VERSION}_amd64.deb
# Verify package
dpkg-deb --info httpc_${VERSION}_amd64.deb
dpkg-deb --contents httpc_${VERSION}_amd64.deb
- name: Create RPM package
run: |
VERSION=$(grep '^version' Cargo.toml | cut -d'"' -f2)
# Create RPM build environment
mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
# Create tarball for RPM
mkdir -p httpc-${VERSION}
cp binaries/httpc-linux-x64 httpc-${VERSION}/httpc
chmod +x httpc-${VERSION}/httpc
# Copy additional files
cp LICENSE httpc-${VERSION}/
cp README.md httpc-${VERSION}/
# Create profiles example
mkdir -p httpc-${VERSION}/etc/httpc
cp packaging/etc/httpc/profiles.example httpc-${VERSION}/etc/httpc/
# Create tarball
tar -czf ~/rpmbuild/SOURCES/httpc-${VERSION}.tar.gz httpc-${VERSION}
# Create RPM spec file
cat > ~/rpmbuild/SPECS/httpc.spec << EOF
Name: httpc
Version: ${VERSION}
Release: 1%{?dist}
Summary: A flexible HTTP client with profile support
License: MIT
URL: https://github.com/samwisely75/httpc
Source0: %{name}-%{version}.tar.gz
BuildRequires: gzip
Requires: glibc >= 2.17
%description
httpc is a flexible HTTP client that supports configuration profiles,
various authentication methods, and custom headers. It's designed for
developers who need a powerful command-line HTTP client for testing
APIs and web services.
%prep
%setup -q
%build
# Binary is already built, no compilation needed
%install
rm -rf %{buildroot}
# Install binary
mkdir -p %{buildroot}%{_bindir}
install -m 755 httpc %{buildroot}%{_bindir}/httpc
# Install configuration
mkdir -p %{buildroot}%{_sysconfdir}/httpc
install -m 644 etc/httpc/profiles.example %{buildroot}%{_sysconfdir}/httpc/profiles.example
# Install documentation
mkdir -p %{buildroot}%{_docdir}/%{name}
install -m 644 README.md %{buildroot}%{_docdir}/%{name}/README.md
install -m 644 LICENSE %{buildroot}%{_docdir}/%{name}/LICENSE
# Create man page
mkdir -p %{buildroot}%{_mandir}/man1
cat > %{buildroot}%{_mandir}/man1/httpc.1 << 'MANEOF'
.TH HTTPC 1 "$(date +'%B %Y')" "httpc ${VERSION}" "User Commands"
.SH NAME
httpc \- A flexible HTTP client with profile support
.SH SYNOPSIS
.B httpc
[\fIOPTIONS\fR] \fIMETHOD\fR \fIURL\fR
.SH DESCRIPTION
\fBhttpc\fP is a flexible HTTP client that supports configuration profiles and various authentication methods.
.SH OPTIONS
.TP
\fB\-p, \-\-profile\fR \fIPROFILE\fR
Use the specified profile from ~/.httpc/profiles
.TP
\fB\-H, \-\-header\fR \fIHEADER\fR
Add custom HTTP header
.TP
\fB\-d, \-\-data\fR \fIDATA\fR
Send data in request body
.TP
\fB\-v, \-\-verbose\fR
Enable verbose output
.TP
\fB\-h, \-\-help\fR
Show help message
.TP
\fB\-V, \-\-version\fR
Show version information
.SH CONFIGURATION
Configuration profiles are stored in ~/.httpc/profiles in INI format.
See %{_sysconfdir}/httpc/profiles.example for configuration examples.
.SH EXAMPLES
.TP
httpc GET https://api.example.com/users
.TP
httpc -p staging POST /api/data -d '{"key": "value"}'
.TP
httpc -H "Authorization: Bearer token" GET /protected
.SH AUTHOR
Written by Satoshi Iizuka.
.SH REPORTING BUGS
Report bugs to: https://github.com/samwisely75/httpc/issues
MANEOF
gzip %{buildroot}%{_mandir}/man1/httpc.1
%files
%{_bindir}/httpc
%config(noreplace) %{_sysconfdir}/httpc/profiles.example
%{_docdir}/%{name}/README.md
%{_docdir}/%{name}/LICENSE
%{_mandir}/man1/httpc.1.gz
%post
# Create httpc config directory if it doesn't exist
if [ ! -d "/etc/httpc" ]; then
mkdir -p /etc/httpc
fi
# Copy example profiles if user doesn't have profiles yet
if [ ! -f "\$HOME/.httpc/profiles" ] && [ -f "/etc/httpc/profiles.example" ]; then
mkdir -p "\$HOME/.httpc"
cp /etc/httpc/profiles.example "\$HOME/.httpc/profiles"
echo "Created default profiles at \$HOME/.httpc/profiles"
echo "Edit this file to configure your API endpoints"
fi
%changelog
* $(date +'%a %b %d %Y') Satoshi Iizuka <[email protected]> - ${VERSION}-1
- Release version ${VERSION}
EOF
# Build RPM
rpmbuild -bb ~/rpmbuild/SPECS/httpc.spec
# Copy RPM to current directory
cp ~/rpmbuild/RPMS/x86_64/httpc-${VERSION}-1.*.rpm .
# Verify package
rpm -qip httpc-${VERSION}-1.*.rpm
rpm -qlp httpc-${VERSION}-1.*.rpm
- name: Upload RPM package
uses: actions/upload-artifact@v4
with:
name: httpc-rpm-package
path: "*.rpm"
if-no-files-found: error
- name: Upload DEB package
uses: actions/upload-artifact@v4
with:
name: httpc-deb-package
path: "*.deb"
if-no-files-found: error
test-binaries:
needs: build
strategy:
matrix:
include:
- os: ubuntu-latest
binary: httpc-linux-x64
- os: macos-latest
binary: httpc-macos-x64
- os: windows-latest
binary: httpc-windows-x64
runs-on: ${{ matrix.os }}
steps:
- name: Download binary
uses: actions/download-artifact@v4
with:
name: ${{ matrix.binary }}
- name: Test binary (Unix)
if: matrix.os != 'windows-latest'
run: |
chmod +x ${{ matrix.binary }}
./${{ matrix.binary }} --version
./${{ matrix.binary }} --help
- name: Test binary (Windows)
if: matrix.os == 'windows-latest'
shell: cmd
run: |
.\%BINARY%.exe --version
.\%BINARY%.exe --help
env:
BINARY: ${{ matrix.binary }}
create-release:
needs: [build, build-packages, test-binaries]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version from branch name
id: extract_version
run: |
if [[ "${{ github.ref_name }}" =~ ^release/(.+)$ ]]; then
VERSION=${BASH_REMATCH[1]}
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "tag_name=v${VERSION}" >> $GITHUB_OUTPUT
echo "Extracted version: ${VERSION}"
else
echo "Error: Could not extract version from branch name: ${{ github.ref_name }}"
exit 1
fi
- name: Create and push release tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
TAG_NAME="${{ steps.extract_version.outputs.tag_name }}"
VERSION="${{ steps.extract_version.outputs.version }}"
RELEASE_BRANCH="release/$VERSION"
echo "Processing tag: $TAG_NAME"
echo "Processing release branch: $RELEASE_BRANCH"
# Check if tag exists locally and delete it
if git tag -l | grep -q "^${TAG_NAME}$"; then
echo "Local tag $TAG_NAME exists, deleting it..."
git tag -d "$TAG_NAME"
fi
# Check if tag exists on remote and delete it
if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then
echo "Remote tag $TAG_NAME exists, deleting it..."
git push origin ":refs/tags/$TAG_NAME"
fi
# Create and push the tag
git tag "$TAG_NAME"
git push origin "$TAG_NAME"
echo "Created and pushed tag: $TAG_NAME"
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Prepare release assets
run: |
mkdir -p release-assets
find artifacts -name "httpc-*" -exec cp {} release-assets/ \;
find artifacts -name "*.deb" -exec cp {} release-assets/ \;
find artifacts -name "*.rpm" -exec cp {} release-assets/ \;
ls -la release-assets/
- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.extract_version.outputs.tag_name }}
name: Release ${{ steps.extract_version.outputs.tag_name }}
draft: false
prerelease: false
files: release-assets/*
body: |
## What's Changed
* Cross-platform release for Windows, macOS, and Linux
* Linux packages available in DEB and RPM formats
* Configuration profiles support for API endpoints
* Flexible HTTP client with authentication support
## Installation
### Using Pre-built Binaries
Download the appropriate binary for your platform from the assets below:
### Windows
- `httpc-windows-x64.exe` - Windows 64-bit (Intel/AMD)
### macOS
- `httpc-macos-x64` - macOS Intel (x64)
- `httpc-macos-arm64` - macOS Apple Silicon (M1/M2)
### Linux
- `httpc-linux-x64` - Linux 64-bit (Intel/AMD)
- `httpc-linux-arm64` - Linux ARM64
- `httpc_*_amd64.deb` - Debian/Ubuntu package
- `httpc-*.rpm` - Red Hat/Fedora/CentOS package
### Using Package Managers (Linux)
**Debian/Ubuntu (.deb):**
```bash
# Download the .deb file from assets below, then:
sudo dpkg -i httpc_*_amd64.deb
```
**Red Hat/Fedora/CentOS (.rpm):**
```bash
# Download the .rpm file from assets below, then:
sudo rpm -i httpc-*.rpm
# Or with DNF/YUM:
sudo dnf install httpc-*.rpm
sudo yum install httpc-*.rpm
```
## Configuration
httpc uses configuration profiles stored in `~/.httpc/profiles`. The package installation will create an example file at:
- Linux: `/etc/httpc/profiles.example`
- Copy this to `~/.httpc/profiles` and customize as needed
Example profile configuration:
```ini
[default]
host = https://api.example.com
@content-type = application/json
@accept = application/json
[local]
host = http://localhost:8080
@content-type = application/json
```
## Usage
```bash
# Basic usage
httpc GET https://api.example.com/users
# Using a profile
httpc -p local GET /api/data
# With custom headers
httpc -H "Authorization: Bearer token" GET /protected
# POST with data
httpc POST /api/data -d '{"key": "value"}'
```
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-homebrew:
name: Publish to Homebrew
runs-on: macos-latest
needs: create-release
steps:
- name: Extract version from ref
id: extract_version
run: |
if [[ "${{ github.ref_name }}" =~ ^release/(.+)$ ]]; then
VERSION=${BASH_REMATCH[1]}
echo "version=${VERSION}" >> $GITHUB_OUTPUT
else
echo "Error: Could not extract version from branch name: ${{ github.ref_name }}"
exit 1
fi
- name: Checkout homebrew tap
uses: actions/checkout@v4
with:
repository: samwisely75/homebrew-tap
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: homebrew-tap
- name: Update formula
working-directory: homebrew-tap
run: |
VERSION=${{ steps.extract_version.outputs.version }}
TAG="v${VERSION}"
# Calculate SHA256 from the release tarball
SHA256=$(curl -L https://github.com/samwisely75/httpc/archive/refs/tags/${TAG}.tar.gz | sha256sum | cut -d ' ' -f 1)
# Create or update the formula
cat > Formula/httpc.rb << EOF
class Httpc < Formula
desc "A flexible HTTP client with profile support"
homepage "https://github.com/samwisely75/httpc"
version "${VERSION}"
license "MIT"
on_macos do
on_arm do
url "https://github.com/samwisely75/httpc/releases/download/${TAG}/httpc-macos-arm64"
sha256 "$(curl -L https://github.com/samwisely75/httpc/releases/download/${TAG}/httpc-macos-arm64 | sha256sum | cut -d ' ' -f 1)"
end
on_intel do
url "https://github.com/samwisely75/httpc/releases/download/${TAG}/httpc-macos-x64"
sha256 "$(curl -L https://github.com/samwisely75/httpc/releases/download/${TAG}/httpc-macos-x64 | sha256sum | cut -d ' ' -f 1)"
end
end
def install
bin.install Dir["*"].first => "httpc"
end
test do
assert_match "httpc #{version}", shell_output("#{bin}/httpc --version")
end
end
EOF
# Commit and push the changes
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/httpc.rb
git commit -m "httpc ${VERSION}"
git push
publish-crates-io:
name: Publish to Crates.io
runs-on: ubuntu-latest
needs: create-release
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Publish to crates.io
run: cargo publish --token ${{ secrets.CRATES_IO_TOKEN }}
merge-to-main:
name: Merge Release to Main
runs-on: ubuntu-latest
needs: [create-release, build, build-packages, test-binaries]
if: startsWith(github.ref, 'refs/heads/release/')
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Need full history for merge
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Merge release to main
run: |
# Determine the source branch
SOURCE_BRANCH=${GITHUB_REF#refs/heads/}
echo "Branch triggered: merging from $SOURCE_BRANCH"
# Switch to main and merge
git checkout main
git pull origin main
# Check if the release branch/tag is already merged
if git merge-base --is-ancestor ${{ github.sha }} HEAD; then
echo "Changes already merged into main"
else
echo "Merging $SOURCE_BRANCH to main..."
git merge --no-ff ${{ github.sha }} -m "Merge release ${{ github.ref_name }} to main - All release artifacts and tests passed"
# Push to main
git push origin main
echo "✅ Successfully merged release to main"
fi
- name: Update develop branch
run: |
# Also merge any release changes back to develop to keep it up to date
git checkout develop
git pull origin develop
# Check if already merged
if git merge-base --is-ancestor ${{ github.sha }} HEAD; then
echo "Changes already in develop"
else
echo "Merging release changes back to develop..."
git merge --no-ff ${{ github.sha }} -m "Merge release ${{ github.ref_name }} back to develop"
git push origin develop
echo "✅ Successfully updated develop branch"
fi
- name: Clean up release branch
if: startsWith(github.ref, 'refs/heads/release/')
run: |
# Delete the release branch after successful merge
RELEASE_BRANCH=${GITHUB_REF#refs/heads/}
echo "Deleting release branch: $RELEASE_BRANCH"
# Try to delete the remote branch
if git ls-remote --heads origin | grep -q "refs/heads/$RELEASE_BRANCH"; then
echo "Attempting to delete remote branch: refs/heads/$RELEASE_BRANCH"
git push origin --delete "$RELEASE_BRANCH" || {
echo "Standard delete failed, trying alternative syntax..."
git push origin ":refs/heads/$RELEASE_BRANCH" || {
echo "⚠️ Could not delete remote branch, may already be deleted"
}
}
else
echo "Remote branch $RELEASE_BRANCH not found, may already be deleted"
fi
echo "✅ Cleaned up release branch"