Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add github action for packaging and publishing python packages to PyPI (#1592) #2126

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
189 changes: 189 additions & 0 deletions .github/workflows/release-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
name: Release Python

on:
release:
types: [published]
workflow_dispatch:
inputs:
release_tag:
description: "The release tag to target"
# Create the sdist and build the wheels, but do not publish to PyPI, only to TestPyPI.
dry_run:
description: Dry run
type: boolean
default: false

permissions:
contents: read

env:
DRY_RUN: ${{ github.event.inputs.dry_run || 'false' }}

jobs:
linux:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: ubuntu-22.04
target: x86_64
- runner: ubuntu-22.04
target: aarch64
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'release' && '' || github.event.inputs.release_tag }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, this means: if the first condition evaluates to true, then && evaluates to its second condition, and || to its first condition. Otherwise, && evaluates to false and || to its second condition.

I'm not a GitHub action expert, and given that workflow expressions are limited (well, maybe they should use Nickel :p), that might be the idiomatic way to do things but I find this a bit confusing.

- uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter --manifest-path py-nickel/Cargo.toml
sccache: 'true'
manylinux: auto
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels-linux-${{ matrix.platform.target }}
path: dist/*

musllinux:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: ubuntu-22.04
target: x86_64
- runner: ubuntu-22.04
target: aarch64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter --manifest-path py-nickel/Cargo.toml
sccache: 'true'
manylinux: musllinux_1_2
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels-musllinux-${{ matrix.platform.target }}
path: dist/*

windows:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: windows-latest
target: x64
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'release' && '' || github.event.inputs.release_tag }}
- uses: actions/setup-python@v5
with:
python-version: 3.x
architecture: ${{ matrix.platform.target }}
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter --manifest-path py-nickel/Cargo.toml
sccache: 'true'
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels-windows-${{ matrix.platform.target }}
path: dist/*

macos:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: macos-13
target: x86_64
- runner: macos-14
target: aarch64
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'release' && '' || github.event.inputs.release_tag }}
- uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter --manifest-path py-nickel/Cargo.toml
sccache: 'true'
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels-macos-${{ matrix.platform.target }}
path: dist/*

sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'release' && '' || github.event.inputs.release_tag }}
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist --manifest-path py-nickel/Cargo.toml
- name: Upload sdist
uses: actions/upload-artifact@v4
with:
name: wheels-sdist
path: dist/*

publish-to-pypi:
name: Publish distribution to PyPI
runs-on: ubuntu-latest
if: env.DRY_RUN == 'false'
needs: [linux, musllinux, windows, macos, sdist]
environment:
name: pypi
url: https://pypi.org/p/py-nickel
permissions:
# Use to sign the release artifacts
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
path: dist/
merge-multiple: true
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

publish-to-testpypi:
name: Publish distribution to TestPyPI
runs-on: ubuntu-latest
needs: [linux, musllinux, windows, macos, sdist]
environment:
name: testpypi
url: https://test.pypi.org/p/py-nickel
permissions:
# Use to sign the release artifacts
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
path: dist/
merge-multiple: true
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
skip-existing: true
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
"lsp/lsp-harness",
"utils",
"wasm-repl",
"pyckel",
"py-nickel",
]
resolver = "2"

Expand Down
2 changes: 1 addition & 1 deletion HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The Nickel repository consist of various crates:
server for Nickel.
- `nickel-lang-utils`: (path: `utils/`). An auxiliary crate regrouping
helpers for tests and benchmarks. Not required to build `nickel` itself.
- `pyckel` (path: `pyckel`). Python bindings to `nickel-lang-core`.
- `py-nickel` (path: `py-nickel`). Python bindings to `nickel-lang-core`.
- `lsp-harness` (path: `lsp/lsp-harness`). A testing harness for the Nickel Language
Server.
- `nickel-repl` (path: `wasm-repl`). An auxiliary crate, re-exporting
Expand Down
4 changes: 2 additions & 2 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Other crates carry the version number of the Nickel language. These are

- `nickel-lang-cli`
- `nickel-lang-lsp`
- `pyckel`
- `py-nickel`

### Prepare

Expand All @@ -73,7 +73,7 @@ following steps manually.
`git checkout -b X.Y.Z-release`
2. Bump the overall workspace version number in `Cargo.toml` to `X.Y.Z`. This
will be automatically propagated to the CLI, the Nickel language server and
Pyckel.
py-nickel.
3. Update the current version number mentioned in `doc/manual/introduction.md`
with the new one set in step 2. Grep for the previous version
number in the various README files, as the latest version is sometimes
Expand Down
5 changes: 3 additions & 2 deletions pyckel/Cargo.toml → py-nickel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "pyckel"
name = "py-nickel"
readme = "README.md"
description = "Python bindings for the Nickel programming language."
authors.workspace = true
Expand All @@ -19,5 +19,6 @@ codespan-reporting.workspace = true
pyo3-build-config.workspace = true

[lib]
name = "nickel"
crate-type = ["cdylib", "rlib"]
bench = false
bench = false
8 changes: 4 additions & 4 deletions pyckel/README.md → py-nickel/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# pyckel
# pynickel

Python bindings to use Nickel.

## Install

```shell
pip install .
pip install py-nickel
```

## Use

```python
import pyckel
import nickel

result = pyckel.run("let x = 1 in { y = x + 2 }")
result = nickel.run("let x = 1 in { y = x + 2 }")
print(result)
# {
# "y": 3
Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions py-nickel/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[build-system]
requires = ["maturin>=1.5,<2.0"]
build-backend = "maturin"

[project]
name = "py-nickel"
requires-python = ">=3.11"
classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
]
dynamic = ["version"]

[tool.maturin]
features = ["pyo3/extension-module"]
4 changes: 2 additions & 2 deletions pyckel/src/lib.rs → py-nickel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use nickel_lang_core::{

use pyo3::{create_exception, exceptions::PyException, prelude::*};

create_exception!(pyckel, NickelException, PyException);
create_exception!(nickel, NickelException, PyException);

/// Turn an internal Nickel error into a PyErr with a fancy diagnostic message
fn error_to_exception<E: Into<Error>, EC: Cache>(error: E, program: &mut Program<EC>) -> PyErr {
Expand Down Expand Up @@ -43,7 +43,7 @@ pub fn run(s: String) -> PyResult<String> {
}

#[pymodule]
pub fn pyckel(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
pub fn nickel(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(run, m)?)?;
Ok(())
}
6 changes: 0 additions & 6 deletions pyckel/pyproject.toml

This file was deleted.

2 changes: 1 addition & 1 deletion scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ echo "++ Prepare release branch from '$RELEASE_BASE_BRANCH'"
# Directories of subcrates following their own independent versioning
independent_crates=(core utils lsp/lsp-harness ./wasm-repl)
# All subcrate directories, including the ones above
all_crates=("${independent_crates[@]}" cli lsp/nls pyckel)
all_crates=("${independent_crates[@]}" cli lsp/nls py-nickel)

workspace_version=$(tomlq -r .workspace.package.version ./Cargo.toml)
workspace_version_array=()
Expand Down
Loading