Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
8 changes: 8 additions & 0 deletions .github/actions/dockerhub-login/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: login to Dockerhub (to prevent image pull trottling)
runs:
using: composite
steps:
- name: docker login
run: |
docker login -u "$DOCKERHUB_USERNAME" --password-stdin <<< "$DOCKERHUB_PASSWORD" || echo "::warning::docker-login failed, ignoring"
shell: bash
17 changes: 17 additions & 0 deletions .github/actions/refetch-artifacts/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Refetch artifacts
runs:
using: "composite"
steps:
- name: download wheel.zip
uses: actions/download-artifact@v4
with:
name: wheel
path: ./dist
- name: download sdist.zip
uses: actions/download-artifact@v4
with:
name: sdist
path: ./dist
- name: inspect
shell: bash
run: ls dist/
19 changes: 19 additions & 0 deletions .github/actions/setup-semantic-release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: setup semantic-release with plugins
runs:
using: composite
steps:
- uses: actions/setup-node@v5
id: setup-node
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ steps.setup-node.node-version }}
- shell: bash
run: |
npm i -g \
semantic-release \
@semantic-release/exec \
@semantic-release/git \
@semantic-release/github \
@semantic-release/changelog \
@google/semantic-release-replace-plugin
51 changes: 51 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Setup base (python, pip cache, tox)
inputs:
python:
description: "Python version to use"
required: true
type: string
default: 3.12
outputs:
'python-version':
value: ${{ steps.python.outputs.python-version }}
runs:
using: "composite"
steps:
- name: pip cache
uses: actions/cache@v4
with:
path: |
~/.cache/pip
key: ${{ runner.os }}-pip-${{ inputs.python }}

- name: Cargo cache
uses: actions/cache/@v4
with:
path: "~/.cargo"
key: ${{ runner.os }}-cargo

- name: Poetry cache
uses: actions/cache/@v4
with:
path: "~/.cache/pypoetry"
key: ${{ runner.os }}-poetry-${{ inputs.python }}
restore-keys: |
${{ runner.os }}-poetry-

- uses: actions/setup-python@v6
id: python
with:
python-version: ${{ inputs.python }}

- name: upgrade pip and install tox
shell: bash
run: |
python -m pip -q install --upgrade pip "setuptools==65.6.2"
pip -q install "tox<4" tox-gh-actions

- name: install Rust and Poetry
shell: bash
run : |
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --profile minimal
source "$HOME/.cargo/env"
pip -q install poetry>=1.2.0
41 changes: 41 additions & 0 deletions .github/workflows/lint-and-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Lint and test
on:
pull_request:
push:
branches:
- master
- 'ci/**' # ci testing, pre-releases
#- 'feature/**'

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup
- name: Lint
id: lint
run: tox -e lint
continue-on-error: true
- name: Emit warning if lint failed
if: ${{ steps.lint.outcome != 'success' }}
run: echo "::warning::Linter failure suppressed (continue-on-error=true)"
test:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
python:
- "3.12"
- "3.11"
- "3.10"
- "3.9.14"
- "3.8"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup
with:
python: ${{ matrix.python }}
- name: Test
run: tox
31 changes: 0 additions & 31 deletions .github/workflows/main.yml

This file was deleted.

146 changes: 146 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: Release

on:
workflow_run: # would only fire after file is merged to master
workflows: ["Lint and test"]
types:
- completed
branches:
- master
- 'ci/**' # ci testing, pre-releases
#- develop # can emit -dev releases but we do not want to
workflow_dispatch:
inputs:
dry_run:
description: "Run in dry-run mode (no publish)"
required: false
default: "true"
push: # only temporary, until this file lands on master (see above)
branches:
- 'ci/**'

# MUSTHAVE: Trusted publisher access for both repos.
# NOTE: according to docs, 'test' repo accounts are ephemeral and can be wiped at any time
# NOTE: 'test' accs are not that ephmeperal -- losing access to sandbox account (2FA issue) effectively locked us out of project; good test for workarounds though
# NOTE: as a part of regaining-control scenario we may use distinct project names in pyroject.toml (e.g. appmap-dev, appmap-ng)
env:
DRY_RUN: ${{ github.event.inputs.dry_run || 'false' }}
pypi_project: appmap
#testpypi_project: appmap-dev # workaround for lost-access scenario
testpypi_project: appmapcitest

jobs:

setup:
runs-on: ubuntu-latest
outputs:
distribution_name: ${{ steps.configure.outputs.distribution_name }}
publish_to: ${{ steps.configure.outputs.publish_to }}
publish_env: ${{ steps.configure.outputs.publish_env }}
steps:
- id: configure
shell: bash
run: |
case "${{ github.ref_name }}" in
ci/*)
echo "publish_env=testpypi" >> $GITHUB_OUTPUT
echo "distribution_name=${{ env.testpypi_project }}" >> $GITHUB_OUTPUT
echo "publish_to=https://test.pypi.org/project/${{ env.testpypi_project }}" >> $GITHUB_OUTPUT
;;
master)
echo "publish_env=pypi" >> $GITHUB_OUTPUT
echo "distribution_name=${{ env.pypi_project }}" >> $GITHUB_OUTPUT
echo "publish_to=https://pypi.org/project/${{ env.pypi_project }}" >> $GITHUB_OUTPUT
;;
*)
echo "publish_env=SKIP" >> $GITHUB_OUTPUT
echo "distribution_name=${{ env.pypi_project }}" >> $GITHUB_OUTPUT
echo "publish_to=https://test.pypi.org/project/${{ env.pypi_project }}" >> $GITHUB_OUTPUT
;;
esac

release:
runs-on: ubuntu-latest
needs: setup
if: github.event_name == 'workflow_dispatch' || (github.event_name=='push' && startsWith(github.ref_name,'ci/') ) || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && (github.event.workflow_run.head_branch == 'master' || startsWith(github.event.workflow_run.head_branch, 'ci/') ) )
permissions:
contents: write
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup-semantic-release # node+semantic-release
- uses: ./.github/actions/setup # poetry
- id: semantic-release # branch policies defined in .releaserc
env:
GIT_AUTHOR_NAME: appland-release
GIT_AUTHOR_EMAIL: release@app.land
GIT_COMMITTER_NAME: appland-release
GIT_COMMITTER_EMAIL: release@app.land
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DISTRIBUTION_NAME: ${{ needs.setup.outputs.distribution_name }}
run: |
if [ "$DRY_RUN" = "true" ]; then
semantic-release --dry-run
else
semantic-release
fi

- name: Upload wheel
if: env.DRY_RUN != 'true'
uses: actions/upload-artifact@v4
with:
name: wheel
path: dist/*.whl
- name: Upload sdist
if: env.DRY_RUN != 'true'
uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
outputs: # not reused in fact
release_tag: ${{ steps.semantic-release.outputs.next_release_tag }}

smoketest:
runs-on: ubuntu-latest
needs: ['setup', 'release']
if: github.event.inputs.dry_run!='true'
continue-on-error: ${{ needs.setup.outputs.distribution_name!='appmap' }} # altered names won't work anyway
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/refetch-artifacts
- name: dockerhub login (for seamless docker pulling)
uses: ./.github/actions/dockerhub-login
env:
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME }}
continue-on-error: true
- run: ci/scripts/run_tests.sh
env:
SMOKETEST_DOCKER_IMAGE: python:3.12-slim
DISTRIBUTION_NAME: ${{ needs.setup.outputs.distribution_name }}

# as a workaround to ownership issues (lost access to project)
publish:
name: publish package on PyPI
needs: ['setup', 'release','smoketest']
if: (( github.event.inputs.dry_run != 'true' ) && ( (needs.setup.outputs.publish_env == 'pypi') || (needs.setup.outputs.publish_env == 'testpypi') ) )
runs-on: ubuntu-latest
environment:
name: ${{ needs.setup.outputs.publish_env }}
url: ${{ needs.setup.outputs.publish_to }}
permissions:
id-token: write
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/refetch-artifacts

- name: Publish to PyPI
if: needs.setup.outputs.publish_env=='pypi'
uses: pypa/gh-action-pypi-publish@release/v1

- name: Publish to TestPyPI
if: needs.setup.outputs.publish_env=='testpypi'
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/ # trailing slash matters!
30 changes: 29 additions & 1 deletion .releaserc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# Allowed number of prerelease rules: 1..3
# While semantic-release allows globs, they must be combined with `prerelease: true` and suffix is derived from name than. It conflicts with PEP440
# PEP440 version rules (not compatible with SemVer): [N!]N(.N)*[{a|b|rc}N][.postN][.devN]
# Consequences:
# - prerelease branches must be explicitly specified, no asterisks
# - prerelease parameter should be one of: a,b,rc,dev,post
# - translation from SemVer prerelease notation to PEP440 is tone in 'replacements' section
branches: # only branches listed here will create releases
- master
- name: ci/trusted_publishing_test
prerelease: dev
#- name: develop
# prerelease: dev
#- name: feature/*
# prerelease: true # will use branch name as suffix
plugins:
- '@semantic-release/commit-analyzer'
- '@semantic-release/release-notes-generator'
Expand All @@ -13,9 +28,22 @@ plugins:
hasChanged: true
numMatches: 1
numReplacements: 1
- - '@google/semantic-release-replace-plugin' # optional SemVer -> PEP440 coercion
- replacements:
- files: [pyproject.toml] # optional: SemVer prerelease -> PEP440 ("1.2.3-dev.1" -> "1.2.3.dev1")
from: '^version = "(\\d+\\.\\d+\\.\\d+)-(dev|post)\\.(\\d+)"'
to: 'version = "\\1.\\2\\3"'
- files: [pyproject.toml] # optional: SemVer prerelease -> PEP440 ("1.2.3-rc.10" -> "1.2.3rc10" )
from: '^version = "(\\d+\\.\\d+\\.\\d+)-(a|b|rc)\\.(\\d+)"'
to: 'version = "\\1\\2\\3"'
- - '@semantic-release/git'
- assets:
- CHANGELOG.md
- pyproject.toml
- - '@semantic-release/exec'
- publishCmd: poetry publish --build
- prepareCmd: |
/bin/bash ./ci/scripts/build_with_poetry.sh
- - '@semantic-release/github':
- assets:
- dist/*.whl
- dist/*.tar.gz
Loading
Loading