-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from brandonchinn178/docs
Update docs, add release workflow
- Loading branch information
Showing
12 changed files
with
463 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Release | ||
on: workflow_dispatch | ||
|
||
jobs: | ||
ci: | ||
uses: ./.github/workflows/ci.yml | ||
|
||
release: | ||
runs-on: ubuntu-latest | ||
needs: | ||
- ci | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
with: | ||
ref: main | ||
|
||
- uses: actions/download-artifact@v3 | ||
with: | ||
name: toml-reader-sdist | ||
path: ./sdist/ | ||
|
||
- name: Load package version | ||
run: scripts/GetVersion.hs | ||
id: version_info | ||
|
||
- name: Load Hackage token secret name | ||
run: | | ||
import re | ||
username = "${{ github.actor }}" | ||
secret_name = "HACKAGE_TOKEN_" + re.sub(r"\W+", "_", username).upper() | ||
print(f"::set-output name=secret_name::{secret_name}") | ||
shell: python | ||
id: hackage_token_secret | ||
|
||
- name: Make release | ||
run: scripts/make-release.sh | ||
env: | ||
gh_token: ${{ secrets.GITHUB_TOKEN }} | ||
hackage_token: ${{ secrets[steps.hackage_token_secret.outputs.secret_name] }} | ||
version: ${{ steps.version_info.outputs.version }} | ||
sdistdir: ./sdist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## v0.1.0.0 | ||
|
||
Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.venv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/usr/bin/env stack | ||
{- stack runghc --package Cabal -} | ||
|
||
import Data.List (intercalate) | ||
import Distribution.Package (packageVersion) | ||
import Distribution.PackageDescription.Parsec (readGenericPackageDescription) | ||
import qualified Distribution.Verbosity as Verbosity | ||
import Distribution.Version (versionNumbers) | ||
|
||
main :: IO () | ||
main = do | ||
packageDesc <- readGenericPackageDescription Verbosity.silent "toml-reader.cabal" | ||
let version = intercalate "." . map show . versionNumbers . packageVersion $ packageDesc | ||
setOutput "version" version | ||
|
||
{- | | ||
Set output for a GitHub action. | ||
https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter | ||
-} | ||
setOutput :: String -> String -> IO () | ||
setOutput name value = putStrLn $ "::set-output name=" ++ name ++ "::" ++ value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -euxo pipefail | ||
HERE="$(builtin cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
|
||
if [[ ! -d "${HERE}/.venv" ]]; then | ||
python3 -m venv "${HERE}/.venv" | ||
"${HERE}/.venv/bin/pip" install requests | ||
fi | ||
|
||
exec "${HERE}/.venv/bin/python3" "${HERE}/make_release.py" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# pyright: strict, reportUnknownMemberType=false | ||
|
||
from __future__ import annotations | ||
|
||
import itertools | ||
import json | ||
import logging | ||
import os | ||
import requests | ||
from pathlib import Path | ||
from typing import Any | ||
|
||
logger = logging.getLogger(__name__) | ||
logging.basicConfig(level=logging.DEBUG) | ||
|
||
|
||
def main(): | ||
gh_token = os.environ["gh_token"] | ||
hackage_token = os.environ["hackage_token"] | ||
version = os.environ["version"] | ||
sdistdir = os.environ["sdistdir"] | ||
repo = os.environ["GITHUB_REPOSITORY"] | ||
sha = os.environ["GITHUB_SHA"] | ||
|
||
version_name = f"v{version}" | ||
|
||
# check inputs | ||
if not hackage_token: | ||
raise Exception( | ||
"Hackage token is not provided (did you add a Secret of the form HACKAGE_TOKEN_<github username>?)" | ||
) | ||
|
||
# ensure release files exist | ||
sdist_archive = Path(sdistdir) / f"toml-reader-{version}.tar.gz" | ||
if not sdist_archive.exists(): | ||
raise Exception(f"File does not exist: {sdist_archive}") | ||
|
||
logger.info(f"Creating release {version_name}") | ||
|
||
# check + parse CHANGELOG | ||
changelog = Path("CHANGELOG.md").read_text() | ||
if not changelog.startswith(f"## {version_name}"): | ||
raise Exception("CHANGELOG doesn't look updated") | ||
version_changes = get_version_changes(changelog) | ||
|
||
create_github_release( | ||
repo=repo, | ||
token=gh_token, | ||
sha=sha, | ||
version_name=version_name, | ||
version_changes=version_changes, | ||
) | ||
|
||
# uploading as candidate because uploads are irreversible, unlike | ||
# GitHub releases, so just to be extra sure, we'll upload this as | ||
# a candidate and manually confirm uploading the package on Hackage | ||
upload_hackage_candidate( | ||
token=hackage_token, | ||
archive=sdist_archive, | ||
) | ||
|
||
logger.info(f"Released toml-reader {version_name}!") | ||
|
||
|
||
def get_version_changes(changelog: str) -> str: | ||
lines = changelog.split("\n") | ||
|
||
# skip initial '## vX.Y.Z' line | ||
lines = lines[1:] | ||
|
||
# take lines until the next '## vX.Y.Z' line | ||
lines = itertools.takewhile(lambda line: not line.startswith("## v"), lines) | ||
|
||
return "\n".join(lines) | ||
|
||
|
||
def create_github_release( | ||
*, | ||
repo: str, | ||
token: str, | ||
sha: str, | ||
version_name: str, | ||
version_changes: str, | ||
): | ||
session = init_session() | ||
session.headers["Accept"] = "application/vnd.github.v3+json" | ||
session.headers["Authorization"] = f"token {token}" | ||
session.headers["User-Agent"] = repo | ||
|
||
payload = { | ||
"tag_name": version_name, | ||
"target_commitish": sha, | ||
"name": version_name, | ||
"body": version_changes, | ||
} | ||
logger.debug(f"Creating release with: {json.dumps(payload)}") | ||
|
||
session.post( | ||
f"https://api.github.com/repos/{repo}/releases", | ||
json=payload, | ||
) | ||
|
||
|
||
def upload_hackage_candidate( | ||
*, | ||
token: str, | ||
archive: Path, | ||
): | ||
session = init_session() | ||
with archive.open("rb") as f: | ||
session.post( | ||
"https://hackage.haskell.org/packages/candidates", | ||
headers={"Authorization": f"X-ApiKey {token}"}, | ||
files={"package": f}, | ||
) | ||
|
||
|
||
def init_session() -> requests.Session: | ||
session = requests.Session() | ||
|
||
def _check_status(r: requests.Response, *args: Any, **kwargs: Any): | ||
r.raise_for_status() | ||
|
||
# https://github.com/python/typeshed/issues/7776 | ||
session.hooks["response"].append( # pyright: ignore[reportFunctionMemberAccess] | ||
_check_status, | ||
) | ||
|
||
return session | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,6 @@ module TOML ( | |
invalidValue, | ||
typeMismatch, | ||
decodeFail, | ||
decodeError, | ||
|
||
-- * TOML types | ||
Value (..), | ||
|
Oops, something went wrong.