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

DM-47128: PyPI deployment and entry points #21

Merged
merged 9 commits into from
Nov 1, 2024
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
72 changes: 69 additions & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ on:
push:
branches:
- main
tags:
- "*"
pull_request:

jobs:
build_and_test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12"]
python-version: ["3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -50,13 +52,77 @@ jobs:
uv pip install -v --system --no-deps -e .

- name: Run tests
env:
DAF_BUTLER_PLUGINS: ${{ github.workspace }}/python/lsst/dax/obscore/cli/resources.yaml
run: |
pytest -r a -v -n 3 --cov=lsst.dax.obscore --cov=tests --cov-report=xml --cov-report=term --cov-branch
butler obscore -h

- name: Upload coverage to codecov
uses: codecov/codecov-action@v4
with:
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}

check-changes:
Copy link
Member Author

Choose a reason for hiding this comment

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

@mwittgen is the plan to put this code in a reusable workflow? It looks like we only made this change in sphgeom and not all the other middleware packages.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes.

outputs:
skip: ${{ steps.check.outputs.skip }}
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check if weekly changed
id: check
run: |
# Get SHA hashes for all weekly tags
weekly_sha=$(git tag -l 'w.*' | while read tag; do
git rev-list -n 1 "${tag}"
done)

# Extract the current tag and its SHA
current_tag=${GITHUB_REF#refs/tags/}
current_sha=$(git rev-list -1 "${current_tag}")

# Count occurrences of the current SHA in the weekly SHA list
n=$(echo "${weekly_sha}" | grep -c "${current_sha}")
echo "Current tag ${current_tag} (${current_sha}) SHA found ${n} time(s)"

# Determine whether to skip the upload based on the count
if [ "${n}" -gt 1 ]; then
echo "Skip upload"
echo "skip=true" >> "${GITHUB_OUTPUT}"
else
echo "Enable upload"
echo "skip=false" >> "${GITHUB_OUTPUT}"
fi

pypi:
name: Upload release to PyPI
runs-on: ubuntu-latest
needs: [build_and_test, check-changes]
permissions:
id-token: write
if: "${{ ! startsWith(github.ref, 'refs/tags/w.') || needs.check-changes.outputs.skip == 'false' }}"

steps:
- uses: actions/checkout@v4
with:
# Need to clone everything to embed the version.
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade setuptools wheel build

- name: Build and create distribution
run: |
python -m build --skip-dependency-check

- name: Upload
uses: pypa/gh-action-pypi-publish@release/v1
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-yaml
args:
- "--unsafe"
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/psf/black
rev: 24.8.0
rev: 24.10.0
hooks:
- id: black
# It is recommended to specify the latest version of Python
Expand All @@ -23,7 +23,7 @@ repos:
name: isort (python)
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.6.5
rev: v0.7.1
hooks:
- id: ruff
- repo: https://github.com/numpy/numpydoc
Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ classifiers = [
"License :: OSI Approved :: GPLv3",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.11",
"Topic :: Scientific/Engineering :: Astronomy",
Expand All @@ -34,6 +35,9 @@ dependencies = [
]
dynamic = ["version"]

[project.entry-points.'butler.cli']
dax_obscore = "lsst.dax.obscore.cli:get_cli_subcommands"

[project.urls]
"Homepage" = "https://github.com/lsst-dm/dax_obscore"

Expand All @@ -42,7 +46,6 @@ postgres = ["psycopg2"]

test = [
"pytest >= 3.2",
"pytest-openfiles >= 0.5.0",
]

[tool.setuptools.packages.find]
Expand Down
1 change: 1 addition & 0 deletions python/lsst/dax/obscore/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from ._get_cli_subcommands import get_cli_subcommands
37 changes: 37 additions & 0 deletions python/lsst/dax/obscore/cli/_get_cli_subcommands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This file is part of dax_obscore.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
# (http://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

__all__ = ["get_cli_subcommands"]

import click

from . import cmd


def get_cli_subcommands() -> list[click.Command]:
"""Return the location of the CLI command plugin definitions.

Returns
-------
commands : `list` [ `click.Command` ]
The command-line subcommands provided by this package.
"""
return [getattr(cmd, c) for c in cmd.__all__]

Check warning on line 37 in python/lsst/dax/obscore/cli/_get_cli_subcommands.py

View check run for this annotation

Codecov / codecov/patch

python/lsst/dax/obscore/cli/_get_cli_subcommands.py#L37

Added line #L37 was not covered by tests
9 changes: 4 additions & 5 deletions python/lsst/dax/obscore/obscore_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@

import astropy.io.votable
import astropy.table
import felis.datamodel
import pyarrow
import sqlalchemy
import yaml
from felis.datamodel import FelisType
from felis.datamodel import Schema as FelisSchema
from lsst.daf.butler import Butler, DataCoordinate, Dimension, Registry, ddl
from lsst.daf.butler.formatters.parquet import arrow_to_numpy
from lsst.daf.butler.registry.obscore import (
Expand Down Expand Up @@ -71,11 +70,11 @@


@cache
def _get_obscore_schema() -> FelisSchema:
def _get_obscore_schema() -> felis.datamodel.Schema:
"""Read the ObsCore schema definition."""
obscore_defn = ResourcePath("resource://lsst.dax.obscore/configs/obscore_nominal.yaml").read()
obscore_data = yaml.safe_load(obscore_defn)
schema = FelisSchema.model_validate(obscore_data)
schema: felis.datamodel.Schema = felis.datamodel.Schema.model_validate(obscore_data)
return schema


Expand Down Expand Up @@ -356,7 +355,7 @@ def to_votable(self, limit: int | None = None) -> astropy.io.votable.tree.VOTabl
for arrow_field in self.schema:
if arrow_field.name in obscore_columns:
ffield = obscore_columns[arrow_field.name]
votable_datatype = FelisType.felis_type(ffield.datatype.value).votable_name
votable_datatype = felis.datamodel.FelisType.felis_type(ffield.datatype.value).votable_name
field = astropy.io.votable.tree.Field(
votable,
name=ffield.name,
Expand Down
Loading