Skip to content

Commit 3b2a58f

Browse files
authored
Merge pull request #10 from maxamillion/rpmbuild
feat(rpm): add packit configuration and RPM spec file
2 parents c5c768f + 99626ea commit 3b2a58f

2 files changed

Lines changed: 206 additions & 0 deletions

File tree

.packit.yaml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# Packit configuration for OpenShell RPM builds via Fedora COPR.
5+
# See https://packit.dev/docs/configuration for full reference.
6+
7+
upstream_tag_template: "v{version}"
8+
upstream_package_name: openshell
9+
downstream_package_name: openshell
10+
specfile_path: openshell.spec
11+
12+
# Packages needed in the SRPM build environment to create vendor tarball
13+
srpm_build_deps:
14+
- rust
15+
- cargo
16+
- git-core
17+
18+
actions:
19+
get-current-version:
20+
# Derive version from the upstream tag nearest to the point where
21+
# midstream diverged from main. This maps the midstream branch back
22+
# to the NVIDIA/OpenShell release it is based on. Tags must be synced
23+
# from upstream to this repo (see README / contributing notes).
24+
#
25+
# NOTE: all bash -c commands are single-quoted to prevent YAML from
26+
# misinterpreting colon-space (": ") sequences as key-value mappings.
27+
- 'bash -c "MERGE_BASE=$(git merge-base origin/midstream origin/main) && git describe --tags --match ''v*'' --abbrev=0 \"$MERGE_BASE\" | sed ''s/^v//''"'
28+
29+
create-archive:
30+
# Step 1: Create source tarball from git working tree.
31+
# Uses git ls-files + tar instead of git archive so the tarball
32+
# reflects any patching that Packit may have done (e.g. version bumps).
33+
- 'bash -c "VERSION=${PACKIT_PROJECT_VERSION} && TMPDIR=$(mktemp -d) && DIR=openshell-${VERSION} && mkdir -p ${TMPDIR}/${DIR} && git ls-files -z | xargs -0 tar cf - | tar xf - -C ${TMPDIR}/${DIR}/ && tar -czf openshell-${VERSION}.tar.gz -C ${TMPDIR} ${DIR} && rm -rf ${TMPDIR}"'
34+
# Step 2: Create vendored Cargo dependencies tarball for offline RPM build.
35+
- 'bash -c "VERSION=${PACKIT_PROJECT_VERSION} && cargo vendor --quiet && tar -cJf openshell-${VERSION}-vendor.tar.xz vendor/ && rm -rf vendor/"'
36+
# Step 3: Return BOTH archive names. Packit maps each line to Source0, Source1, etc.
37+
- 'bash -c "echo openshell-${PACKIT_PROJECT_VERSION}.tar.gz && echo openshell-${PACKIT_PROJECT_VERSION}-vendor.tar.xz"'
38+
39+
fix-spec-file:
40+
# Update Source0 to the generated tarball name
41+
- 'bash -c "sed -i \"s|^Source0:.*|Source0: openshell-${PACKIT_PROJECT_VERSION}.tar.gz|\" openshell.spec"'
42+
# Update Source1 to the generated vendor tarball name
43+
- 'bash -c "sed -i \"s|^Source1:.*|Source1: openshell-${PACKIT_PROJECT_VERSION}-vendor.tar.xz|\" openshell.spec"'
44+
# Update Version
45+
- 'bash -c "sed -i -r \"s/^Version:(\\s*)\\S+/Version:\\1${PACKIT_RPMSPEC_VERSION}/\" openshell.spec"'
46+
# Update Release
47+
- 'bash -c "sed -i -r \"s/^Release:(\\s*)\\S+/Release:\\1${PACKIT_RPMSPEC_RELEASE}%{?dist}/\" openshell.spec"'
48+
49+
jobs:
50+
# Build on every pull request targeting midstream for CI validation
51+
- job: copr_build
52+
trigger: pull_request
53+
branch: midstream
54+
identifier: midstream-pr
55+
targets:
56+
- fedora-all
57+
- epel-10
58+
59+
# Build on GitHub releases for publishable RPMs.
60+
# NOTE: Release builds are tag-based. Only create GitHub releases from
61+
# tags on the midstream branch to ensure builds use midstream content.
62+
# See: https://packit.dev/docs/configuration/upstream/copr_build#using-a-custom-copr-project
63+
- job: copr_build
64+
trigger: release
65+
owner: "maxamillion"
66+
project: "openshell"
67+
targets:
68+
- fedora-all
69+
- epel-10
70+
preserve_project: true
71+
list_on_homepage: true

openshell.spec

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
%global crate openshell
5+
6+
# Cargo/Rust builds with vendored deps do not produce debugsource listings
7+
# in the format redhat-rpm-config expects (especially on EPEL).
8+
%global debug_package %{nil}
9+
10+
Name: openshell
11+
Version: 0.0.20
12+
Release: 1%{?dist}
13+
Summary: Safe, sandboxed runtimes for autonomous AI agents
14+
15+
License: Apache-2.0
16+
URL: https://github.com/LobsterTrap/OpenShell
17+
Source0: %{name}-%{version}.tar.gz
18+
Source1: %{name}-%{version}-vendor.tar.xz
19+
20+
ExclusiveArch: x86_64 aarch64
21+
22+
# Rust build dependencies
23+
# NOTE: MSRV is 1.88 (Rust edition 2024). As of mid-2025, this requires
24+
# Fedora Rawhide or newer. Stable Fedora and EPEL-10 may ship older Rust;
25+
# adjust targets in .packit.yaml accordingly or provide a supplementary
26+
# Rust toolchain via additional_repos in the COPR build config.
27+
BuildRequires: rust >= 1.88
28+
BuildRequires: cargo
29+
BuildRequires: gcc
30+
BuildRequires: gcc-c++
31+
BuildRequires: make
32+
BuildRequires: cmake
33+
BuildRequires: pkg-config
34+
35+
# Python sub-package build dependencies
36+
BuildRequires: python3-devel
37+
38+
%description
39+
OpenShell provides safe, sandboxed runtimes for autonomous AI agents.
40+
It offers a CLI for managing gateways, sandboxes, and providers with
41+
policy-enforced egress routing, credential proxying, and privacy-aware
42+
LLM inference routing.
43+
44+
# --- Python SDK sub-package ---
45+
%package -n python3-%{name}
46+
Summary: OpenShell Python SDK for agent execution and management
47+
Requires: python3-cloudpickle >= 3.0
48+
Requires: python3-grpcio >= 1.60
49+
Requires: python3-protobuf >= 4.25
50+
Recommends: %{name}
51+
52+
%description -n python3-%{name}
53+
Python SDK for OpenShell providing programmatic access to sandbox
54+
management, agent execution, and inference routing via gRPC.
55+
56+
%prep
57+
%autosetup -n %{name}-%{version}
58+
59+
# Extract vendored Cargo dependencies
60+
tar xf %{SOURCE1}
61+
62+
# Configure Cargo to use vendored dependencies for offline build
63+
mkdir -p .cargo
64+
cat > .cargo/config.toml << 'EOF'
65+
[source.crates-io]
66+
replace-with = "vendored-sources"
67+
68+
[source.vendored-sources]
69+
directory = "vendor"
70+
EOF
71+
72+
# Patch workspace version from placeholder to actual version
73+
sed -i 's/^version = "0.0.0"/version = "%{version}"/' Cargo.toml
74+
grep -q 'version = "%{version}"' Cargo.toml || (echo "ERROR: Cargo.toml version patch failed" && exit 1)
75+
76+
%build
77+
# Build only the CLI binary
78+
export CARGO_BUILD_JOBS=%{_smp_build_ncpus}
79+
cargo build --release --bin openshell
80+
81+
%install
82+
# Install CLI binary
83+
install -Dpm 0755 target/release/%{name} %{buildroot}%{_bindir}/%{name}
84+
85+
# Install Python SDK modules (test files are intentionally excluded)
86+
install -d %{buildroot}%{python3_sitelib}/%{name}
87+
install -d %{buildroot}%{python3_sitelib}/%{name}/_proto
88+
89+
install -pm 0644 python/%{name}/__init__.py %{buildroot}%{python3_sitelib}/%{name}/
90+
install -pm 0644 python/%{name}/sandbox.py %{buildroot}%{python3_sitelib}/%{name}/
91+
install -pm 0644 python/%{name}/_proto/__init__.py %{buildroot}%{python3_sitelib}/%{name}/_proto/
92+
install -pm 0644 python/%{name}/_proto/*.py %{buildroot}%{python3_sitelib}/%{name}/_proto/
93+
94+
# Create dist-info so importlib.metadata can resolve the package version
95+
install -d %{buildroot}%{python3_sitelib}/%{name}-%{version}.dist-info
96+
cat > %{buildroot}%{python3_sitelib}/%{name}-%{version}.dist-info/METADATA << EOF
97+
Metadata-Version: 2.1
98+
Name: %{name}
99+
Version: %{version}
100+
Summary: OpenShell Python SDK for agent execution and management
101+
License: Apache-2.0
102+
Requires-Python: >=3.12
103+
Requires-Dist: cloudpickle>=3.0
104+
Requires-Dist: grpcio>=1.60
105+
Requires-Dist: protobuf>=4.25
106+
EOF
107+
108+
# INSTALLER marker per PEP 376
109+
echo "rpm" > %{buildroot}%{python3_sitelib}/%{name}-%{version}.dist-info/INSTALLER
110+
111+
# RECORD can be empty for RPM-managed installs
112+
touch %{buildroot}%{python3_sitelib}/%{name}-%{version}.dist-info/RECORD
113+
114+
%check
115+
# Smoke-test the CLI binary
116+
%{buildroot}%{_bindir}/%{name} --version
117+
118+
# Smoke-test the Python SDK version metadata via importlib.metadata.
119+
# We query the dist-info directly rather than importing the package because
120+
# the full import pulls in grpcio and other runtime deps not present in the
121+
# build environment.
122+
PYTHONPATH=%{buildroot}%{python3_sitelib} %{python3} -c "from importlib.metadata import version; v = version('openshell'); print(v); assert v == '%{version}', f'expected %{version}, got {v}'"
123+
124+
%files
125+
%license LICENSE
126+
%doc README.md
127+
%{_bindir}/%{name}
128+
129+
%files -n python3-%{name}
130+
%license LICENSE
131+
%{python3_sitelib}/%{name}/
132+
%{python3_sitelib}/%{name}-%{version}.dist-info/
133+
134+
%changelog
135+
%autochangelog

0 commit comments

Comments
 (0)