Skip to main content

pullup

Install

pip install pullup

Cloud integrations load only when used.

Project detection

Project detects the release flow from files in the project directory.

project = Project(root)
project.kind, [step.id for step in project.steps()]
('nbdev', ['prepare', 'bump', 'gh', 'pypi'])

Running steps

Steps run in one PTY. Automatic execution stops at the first failure.

pipeline = Pipeline(root, dir='.demo')
pipeline.save([{'id': 'hello', 'cmd': 'say hello',
                'argv': [sys.executable, '-c', 'print("ready")']}])
await pipeline.start()
pipeline.state()['done'], pipeline.tail().splitlines()[-2:]
(False, ['', '❯ say hello'])

Plan storage

Plans are written only below the project directory.

custom = Pipeline(root, dir='.myapp')
custom.save([{'id': 'show', 'cmd': 'show', 'argv': [sys.executable, '-c', 'print("saved")']}])
custom.path.relative_to(root)
Path('.myapp/pipeline.json')

Deployment pipelines

Deploy runs a project’s deployment script. Drive exposes each operation as a library call.

Deploy(root).state()['kind'], Drive(root).state()['kind']
('deploy', 'drive')

Workflows

Local workflow inspection needs no GitHub credentials.

workflow_dir = root/'.github'/'workflows'
workflow_dir.mkdir(parents=True)
(workflow_dir/'ci.yml').write_text('''name: CI
on: push
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: pytest
''')
workflows = Workflows(root)
[(row['name'], [job['id'] for job in row['jobs']]) for row in workflows.parsed()]
[('CI', ['test'])]

Environment

A pipeline injects required values into the child without changing the parent environment.

class Values:
    def get(self, key, secret=True): return 'demo-token' if key == 'DEMO_TOKEN' else ''
    def values(self, keys): return {key: self.get(key) for key in keys if self.get(key)}

with_values = Pipeline(root, env=Values(), dir='.env-demo')
with_values.save([{'id': 'env', 'cmd': 'read environment', 'needs': ['DEMO_TOKEN'],
                   'argv': [sys.executable, '-c', 'import os; print(os.environ["DEMO_TOKEN"])']}])
await with_values.start()
with_values.tail().splitlines()[-2:]
['', '❯ read environment']

Package errors

blame identifies the deepest selected-package frame.

trace = '''Traceback (most recent call last):
  File "/tmp/pullup/demo.py", line 7, in release
    raise RuntimeError("stopped")
RuntimeError: stopped
'''
blame(trace, family=['pullup'])
{'package': 'pullup',
 'file': '/tmp/pullup/demo.py',
 'line': 7,
 'fn': 'release',
 'error': 'RuntimeError: stopped',
 'open': '/tmp/pullup/demo.py',
 'checkout': '',
 'version': '0.0.4'}

Infrastructure

Infra.status reports provider and token availability without making a request.

infra = Infra(env={})
infra.status()
{'vpseasy': True,
 'cfeasy': True,
 'hcloud_token': True,
 'cf_token': False,
 'keys': ['HCLOUD_TOKEN', 'CLOUDFLARE_API_TOKEN']}

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pullup-0.0.5.tar.gz (46.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pullup-0.0.5-py3-none-any.whl (44.6 kB view details)

Uploaded Python 3

File details

Details for the file pullup-0.0.5.tar.gz.

File metadata

  • Download URL: pullup-0.0.5.tar.gz
  • Upload date:
  • Size: 46.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.1

File hashes

Hashes for pullup-0.0.5.tar.gz
Algorithm Hash digest
SHA256 750c1194cfc1b905ad2dfbf6ab9918255481b99cfbd4bd0e41e4af4c87b674dc
MD5 77c9fd10883ee8464034bf721eb88a5d
BLAKE2b-256 ee1fd936bc1cc4a08d6c9ee36d8df9e1a2c99de02e809aed6800b43df2b0bad9

See more details on using hashes here.

File details

Details for the file pullup-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: pullup-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 44.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.1

File hashes

Hashes for pullup-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 a4b32d11a7c8f58e97e98baff68bbfe6dcf18583a3fd6010ed6235cb89a26036
MD5 ccbd7c5d9294a2aec8ef260beb86c1b5
BLAKE2b-256 6a2ca5957369d1ab1f732a8910d3ae60ee771e0e3718a64804888467a0951972

See more details on using hashes here.

Release history Release notifications | RSS feed

0.0.6

2 files

This release

0.0.5 This release

2 files

0.0.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page