Skip to content

Commit

Permalink
Publish static index to GitHub pages in CI (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb authored Mar 6, 2024
1 parent 4e2b423 commit 5b224e8
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 101 deletions.
86 changes: 19 additions & 67 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ env:

permissions:
id-token: write # Needed for AWS CodeArtifact OIDC
contents: read
contents: write # Needed for GH pages updates

on:
pull_request:
Expand All @@ -17,12 +17,6 @@ on:
branches:
- main

# schedule:
# Run every 90 minutes; will only do work if the last job succeeded.
# This ensures that after rate limits are encountered, we attempt to publish again.
# PyPI has a 60 minute rate limit for project creation.
# - cron: "*/90 * * * *"

jobs:
publish-packages:
name: python-${{ matrix.python-version }}, ${{ matrix.os }}
Expand All @@ -42,60 +36,26 @@ jobs:
steps:
- uses: actions/checkout@v4

# Only runs during the scheduled job
# The rest of the workflow will be skipped during scheduled runs unless the last run failed
- name: Check status of last workflow run
id: check_last_run
if: github.event.schedule
run: |
WORKFLOW_ID=$( \
curl \
--silent \
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
--header 'content-type: application/json' \
${{ github.api_url }}/repos/${{ github.repository }}/actions/runs/${{ github.run_id }} \
| jq -r .workflow_id \
)
CONCLUSION=$( \
curl \
--silent \
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
--header 'content-type: application/json' \
"${{ github.api_url }}/repos/${{ github.repository }}/actions/workflows/$WORKFLOW_ID/runs?per_page=1&status=completed&branch=main" \
| jq -r .workflow_runs[0].conclusion \
)
echo "conclusion=$CONCLUSION"
echo "conclusion=$CONCLUSION" >> $GITHUB_OUTPUT
# Implementation based on https://github.com/MercymeIlya/last-workflow-status
- name: Set up Poetry
if: steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure'
run: |
pipx install poetry==${{ env.POETRY_VERSION }}
- name: Set up Python ${{ matrix.python-version }}
if: steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure'
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: poetry

- name: Install zsh
if: steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure'
run: |
sudo apt-get update
sudo apt-get install zsh
- name: Install packages
if: steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure'
run: |
poetry install --extras index
- name: Collect scenarios
if: steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure'
run: |
scenarios=(scenarios/**/*.json)
Expand All @@ -111,14 +71,12 @@ jobs:
shell: zsh {0}

- name: View scenarios
if: steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure'
run: |
poetry run packse view $SCENARIOS
- name: Build scenarios
if: steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure'
run: |
poetry run packse build --skip-root --short-names $SCENARIOS
poetry run packse build --skip-root --no-hash $SCENARIOS
- name: Publish scenarios [local]
if: github.ref != 'refs/heads/main'
Expand All @@ -132,27 +90,21 @@ jobs:
# Shutdown the index server
poetry run packse index down
- name: Configure AWS credentials
if: github.ref == 'refs/heads/main' && (steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure')
uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::590183856360:role/PublishGitHubPackseIsolated
role-session-name: PacksePublishPackage
role-duration-seconds: 900

- name: Publish scenarios [aws]
if: github.ref == 'refs/heads/main' && (steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure')
env:
PACKSE_PUBLISH_USERNAME: "aws"
- name: Publish scenarios [gh pages]
if: github.ref == 'refs/heads/main'
run: |
export PACKSE_PUBLISH_PASSWORD=$(aws codeartifact get-authorization-token --domain astral --domain-owner 590183856360 --region us-east-2 --query authorizationToken --output text)
export INDEX_URL=$(aws codeartifact get-repository-endpoint --domain astral --domain-owner 590183856360 --repository astral-isolated --region us-east-2 --format pypi --query repositoryEndpoint --output text)
poetry run packse publish --index-url "$INDEX_URL" --skip-existing dist/* vendor/build
- name: Publish scenarios [test pypi]
if: github.ref == 'refs/heads/main' && (steps.check_last_run.outcome == 'skipped' || steps.check_last_run.outputs.conclusion == 'failure')
env:
PACKSE_PUBLISH_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
run: |
poetry run packse publish --skip-existing dist/*
commit=$(./scripts/version parts | jq -r ".short_hash")
poetry run packse index build --no-hash --dist-dir ./dist $SCENARIOS
git fetch origin gh-pages
git branch gh-pages FETCH_HEAD
git checkout gh-pages
git config user.name "$GITHUB_ACTOR"
git config user.email "[email protected]"
mkdir "$commit"
cp -r index/* "./$commit"
git add "$commit"
git commit -m "Publish scenarios for $commit"
git push --set-upstream origin gh-pages
24 changes: 23 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
- "[0-9]+.[0-9]+[ab][0-9]+"

jobs:
release:
release-package:
name: Release to PyPI
runs-on: ubuntu-latest

Expand All @@ -38,3 +38,25 @@ jobs:
run: |
poetry version "${GITHUB_REF#refs/*/}"
poetry publish --build
release-scenarios:
name: Publish scenarios
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Publish scenarios to GitHub Pages
run: |
poetry run packse index build --no-hash scenarios/*.json
git fetch origin gh-pages
git branch gh-pages FETCH_HEAD
git checkout gh-pages
git config user.name "$GITHUB_ACTOR"
git config user.email "[email protected]"
mkdir "${GITHUB_REF#refs/*/}"
cp -r index/* "${GITHUB_REF#refs/*/}"
git add "${GITHUB_REF#refs/*/}"
git commit -m "Publish scenarios for $commit"
git push --set-upstream origin gh-pages
13 changes: 10 additions & 3 deletions scripts/version
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ parts
Display all available version parts.
Format: {timestamp: str, short_hash: str, closest_tag: str, distance: int}
$ version parts
{'timestamp': '1663305183', 'short_hash': '440f9b6', 'closest_tag': '0.0.0', 'distance': 50}
$ version parts | jq
{
"timestamp": "1709759768",
"closest_tag": "0.2.0",
"distance": 4,
"short_hash": "4e2b423"
}
local
Generate a PEP 440 compliant local version tag.
Expand Down Expand Up @@ -86,7 +91,9 @@ if __name__ == "__main__":
parts = get_version_parts()

if mode == "parts":
print(parts)
import json

print(json.dumps(parts))

elif mode == "local":
print("{closest_tag}+{distance}.{short_hash}".format(**parts))
Expand Down
13 changes: 10 additions & 3 deletions src/packse/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def _call_index_build(args):
args.targets,
short_names=args.short_names,
no_hash=args.no_hash,
dist_dir=args.dist_dir,
)


Expand Down Expand Up @@ -171,7 +172,7 @@ def _call_list(args):

list(
targets,
args.no_versions,
args.no_hash,
skip_invalid,
args.no_sources,
short_names=args.short_names,
Expand Down Expand Up @@ -460,6 +461,12 @@ def _add_index_parser(subparsers):
action="store_true",
help="Exclude scenario version hashes from generated packages.",
)
build.add_argument(
"--dist-dir",
type=Path,
default=None,
help="An existing distribution directory to use. If provided, the scenarios will not be rebuilt.",
)
build.set_defaults(call=_call_index_build)

_add_shared_arguments(parser)
Expand All @@ -478,9 +485,9 @@ def _add_list_parser(subparsers):
help="The scenario files to load",
)
parser.add_argument(
"--no-versions",
"--no-hash",
action="store_true",
help="Do not include in the scenario versions in the displayed names.",
help="Do not include in the scenario version hashes in the displayed names.",
)
parser.add_argument(
"--skip-invalid",
Expand Down
26 changes: 14 additions & 12 deletions src/packse/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,23 +316,26 @@ def build_index(
targets: list[Path],
no_hash: bool,
short_names: bool,
dist_dir: Path | None,
):
out_path = Path("./index")
if out_path.exists():
shutil.rmtree(out_path)

with tempfile.TemporaryDirectory() as tmpdir:
tmpdir = Path(tmpdir)
logger.info("Building distributions...")
build(
targets,
rm_destination=True,
skip_root=False,
short_names=short_names,
no_hash=no_hash,
dist_dir=tmpdir / "dist",
build_dir=tmpdir / "build",
)
if not dist_dir:
logger.info("Building distributions...")
build(
targets,
rm_destination=True,
skip_root=False,
short_names=short_names,
no_hash=no_hash,
dist_dir=tmpdir / "dist",
build_dir=tmpdir / "build",
)
dist_dir = tmpdir / "dist"

out_path.mkdir()
(out_path / "files").mkdir()
Expand All @@ -344,8 +347,7 @@ def build_index(
package["dists"] = []
for version in package["versions"]:
for file in Path(
tmpdir
/ "dist"
dist_dir
/ (
scenario["name"]
if no_hash
Expand Down
4 changes: 2 additions & 2 deletions src/packse/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

def list(
targets: list[Path],
no_versions: bool = False,
no_hash: bool = False,
skip_invalid: bool = False,
no_sources: bool = False,
short_names: bool = False,
Expand Down Expand Up @@ -45,7 +45,7 @@ def list(
for scenario in scenarios:
scenario = cast(Scenario, scenario)

if no_versions:
if no_hash:
name = scenario.name
else:
name = scenario_hash(scenario)
Expand Down
22 changes: 11 additions & 11 deletions tests/__snapshots__/test_list.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@
''',
})
# ---
# name: test_list_no_hash
dict({
'exit_code': 0,
'stderr': '',
'stdout': '''
scenarios/example.json
example

''',
})
# ---
# name: test_list_no_sources
dict({
'exit_code': 0,
Expand All @@ -37,17 +48,6 @@
'stdout': '<not included>',
})
# ---
# name: test_list_no_versions
dict({
'exit_code': 0,
'stderr': '',
'stdout': '''
scenarios/example.json
example

''',
})
# ---
# name: test_list_one_target_does_not_exist
dict({
'exit_code': 1,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ def test_list_no_target_finds_all_valid_scenarios(snapshot):
)


def test_list_no_versions(snapshot):
def test_list_no_hash(snapshot):
target = __development_base_path__ / "scenarios" / "example.json"
assert snapshot_command(["list", str(target), "--no-versions"]) == snapshot
assert snapshot_command(["list", str(target), "--no-hash"]) == snapshot


def test_list_short_names(snapshot):
Expand Down

0 comments on commit 5b224e8

Please sign in to comment.