From 6ef1f903b3b9467497ad9dfc0ca348dbd94fcd69 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 15 Oct 2023 17:55:35 -0400 Subject: [PATCH] feat: initial version --- .github/workflows/ci.yml | 139 ++++++++++ .gitignore | 164 ++++++++++++ Dockerfile | 14 + action.yml | 43 +++ action/__init__.py | 0 action/main.py | 318 ++++++++++++++++++++++ codecov.yml | 15 ++ requirements-dev.txt | 2 + requirements.txt | 2 + tests/conftest.py | 124 +++++++++ tests/data/set0/CHANGELOG.md | 6 + tests/data/set0/changes.txt | 1 + tests/data/set0/date.txt | 1 + tests/data/set0/url.txt | 1 + tests/data/set0/version.txt | 1 + tests/data/set1/CHANGELOG.md | 492 +++++++++++++++++++++++++++++++++++ tests/data/set1/changes.txt | 78 ++++++ tests/data/set1/date.txt | 1 + tests/data/set1/url.txt | 1 + tests/data/set1/version.txt | 1 + tests/unit/test_main.py | 71 +++++ 21 files changed, 1475 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 action.yml create mode 100644 action/__init__.py create mode 100644 action/main.py create mode 100644 codecov.yml create mode 100644 requirements-dev.txt create mode 100644 requirements.txt create mode 100644 tests/conftest.py create mode 100644 tests/data/set0/CHANGELOG.md create mode 100644 tests/data/set0/changes.txt create mode 100644 tests/data/set0/date.txt create mode 100644 tests/data/set0/url.txt create mode 100644 tests/data/set0/version.txt create mode 100644 tests/data/set1/CHANGELOG.md create mode 100644 tests/data/set1/changes.txt create mode 100644 tests/data/set1/date.txt create mode 100644 tests/data/set1/url.txt create mode 100644 tests/data/set1/version.txt create mode 100644 tests/unit/test_main.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e1ea617 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,139 @@ +--- +name: CI + +on: + pull_request: + branches: [master] + types: [opened, synchronize, reopened] + push: + branches: [master] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + pytest: + strategy: + fail-fast: false + matrix: + os: + - ubuntu-20.04 + - ubuntu-22.04 + + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Python Dependencies + run: | + python -m pip install --upgrade pip setuptools wheel + python -m pip install --upgrade -r requirements.txt + python -m pip install --upgrade -r requirements-dev.txt + + - name: Test with pytest + id: test + env: + INPUT_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: bash + run: | + python -m pytest \ + -rxXs \ + --tb=native \ + --verbose \ + --cov=action \ + tests + + - name: Upload coverage + # any except cancelled or skipped + if: >- + always() && + (steps.test.outcome == 'success' || steps.test.outcome == 'failure') && + (matrix.docker == false) + uses: codecov/codecov-action@v3 + with: + flags: ${{ matrix.os }} + + action: + strategy: + fail-fast: false + matrix: + os: + - ubuntu-20.04 + - ubuntu-22.04 + set: + - '0' + - '1' + + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run Action + id: action + uses: ./ + with: + changelog_path: ./tests/data/set${{ matrix.set }}/CHANGELOG.md + fail_on_events_api_error: false + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Print action outputs + shell: bash + run: | + echo "changelog_exists: ${{ steps.action.outputs.changelog_exists }}" + echo "changelog_changes: ${{ steps.action.outputs.changelog_changes }}" + echo "changelog_date: ${{ steps.action.outputs.changelog_date }}" + echo "changelog_url: ${{ steps.action.outputs.changelog_url }}" + echo "changelog_version: ${{ steps.action.outputs.changelog_version }}" + echo "changelog_release_exists: ${{ steps.action.outputs.changelog_release_exists }}" + echo "publish_stable_release: ${{ steps.action.outputs.publish_stable_release }}" + echo "release_version: ${{ steps.action.outputs.release_version }}" + echo "release_build: ${{ steps.action.outputs.release_build }}" + echo "release_tag: ${{ steps.action.outputs.release_tag }}" + + - name: Verify changelog_exists + shell: bash + run: | + if [[ "${{ steps.action.outputs.changelog_exists }}" != "true" ]]; then + echo "changelog_exists is not true" + exit 1 + fi + + - name: Verify changelog_changes + shell: bash + run: | + expected_changes=$(cat ./tests/data/set${{ matrix.set }}/changes.txt) + if [[ "${{ steps.action.outputs.changelog_changes }}" != "{expected_changes}" ]]; then + echo "changelog_changes does not match expected" + exit 1 + fi + + - name: Verify changelog_date + shell: bash + run: | + expected_date=$(cat ./tests/data/set${{ matrix.set }}/date.txt) + if [[ "${{ steps.action.outputs.changelog_date }}" != "{expected_date}" ]]; then + echo "changelog_date does not match expected" + exit 1 + fi + + - name: Verify changelog_url + shell: bash + run: | + expected_url=$(cat ./tests/data/set${{ matrix.set }}/url.txt) + if [[ "${{ steps.action.outputs.changelog_url }}" != "{expected_url}" ]]; then + echo "changelog_url does not match expected" + exit 1 + fi + + - name: Verify changelog_version + shell: bash + run: | + expected_version=$(cat ./tests/data/set${{ matrix.set }}/version.txt) + if [[ "${{ steps.action.outputs.changelog_version }}" != "{expected_version}" ]]; then + echo "changelog_version does not match expected" + exit 1 + fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d401e2a --- /dev/null +++ b/.gitignore @@ -0,0 +1,164 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + +# project specific ignores +github_*.md +github/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..843fa90 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.12-alpine3.18 AS base + +RUN python -m pip install --upgrade pip setuptools wheel + +COPY . /app + +WORKDIR /app +RUN python -m pip install --upgrade -r requirements.txt + +# github will mount the `GITHUB_WORKSPACE` directory here +# https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#workdir +WORKDIR /app/github/workspace + +ENTRYPOINT ["python", "/app/action/main.py"] diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..a831b99 --- /dev/null +++ b/action.yml @@ -0,0 +1,43 @@ +--- +name: "Setup Release" +description: "Parse the changelog and setup the release parameters." +author: "LizardByte" + +inputs: + changelog_path: + description: "Path to the changelog file, relative to the GitHub workspace." + default: "CHANGELOG.md" + required: false + fail_on_events_api_error: + description: "Whether to fail if the GitHub Events API returns an error." + default: 'false' + required: false + github_token: + description: "GitHub token to use for API requests." + required: true + +outputs: + changelog_changes: + description: "List of changes in the latest version." + changelog_date: + description: "Date of the latest version in the format: `yyyy.m.d`" + changelog_exists: + description: "Whether the changelog exists." + changelog_release_exists: + description: "Whether the release exists in GitHub." + changelog_url: + description: "URL to the latest version in the changelog." + changelog_version: + description: "Latest version in the changelog." + publish_stable_release: + description: "Whether to publish a stable release." + release_version: + description: "Version of the release to make." + release_build: + description: "Build number of the release to make." + release_tag: + description: "Tag of the release to make. e.g. `vYYYY.M.D-Build` or `vYYYY.M.D`" + +runs: + using: "docker" + image: "Dockerfile" diff --git a/action/__init__.py b/action/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/action/main.py b/action/main.py new file mode 100644 index 0000000..0fdeeae --- /dev/null +++ b/action/main.py @@ -0,0 +1,318 @@ +# standard imports +import os +import re + +# lib imports +from dotenv import load_dotenv +import requests + +# Load the environment variables from the Environment File +load_dotenv() + +# Get the repository name from the environment variables +REPOSITORY_NAME = os.environ["GITHUB_REPOSITORY"] + +# Get the GitHub API token from the environment variables +GITHUB_API_TOKEN = os.environ["INPUT_GITHUB_TOKEN"] + +# Define the headers for the GitHub API +GITHUB_HEADERS = {'Authorization': f'token {GITHUB_API_TOKEN}'} + + +def append_github_step_summary(message: str): + """ + Append a message to the GitHub Status Summary. + + Parameters + ---------- + message : str + The message to append to the GitHub Status Summary. This support markdown. + """ + with open(os.path.abspath(os.environ["GITHUB_STEP_SUMMARY"]), "a") as f: + f.write(f'{message}\n') + + +def set_github_action_output(output_name: str, output_value: str): + """ + Set the output value by writing to the outputs in the Environment File, mimicking the behavior defined __. + + Parameters + ---------- + output_name : str + Name of the output. + output_value : str + Value of the output. + """ + with open(os.path.abspath(os.environ["GITHUB_OUTPUT"]), "a") as f: + f.write(f'{output_name}={output_value}\n') + + +def check_if_changelog_exists(changelog_path: str) -> bool: + """ + Check if the changelog exists. + + This function will first check if the changelog exists at the given path. + + Parameters + ---------- + changelog_path : str + Full path to the changelog file. + + Returns + ------- + bool + True if the changelog exists, False otherwise. + """ + # Check if the changelog exists + if os.path.exists(changelog_path): + return True + else: + return False + + +def check_release(version: str) -> bool: + """ + Check if the release exists in the GitHub API. + + This function will check if the release exists in the GitHub API. + + Parameters + ---------- + version : str + Version number of the release. + + Returns + ------- + bool + True if the release exists, False otherwise. + """ + # Get the release from the GitHub API + github_api_url = f'https://api.github.com/repos/{REPOSITORY_NAME}/releases/tags/v{version}' + response = requests.get(github_api_url, headers=GITHUB_HEADERS) + + # Check if the release exists + if response.status_code == 200: + return True + else: + return False + + +def get_repo_default_branch() -> str: + """ + Get the default branch of the repository from the GitHub API. + + This function will get the default branch of the repository from the GitHub API. + + Returns + ------- + str + Default branch of the repository. + """ + github_api_url = f'https://api.github.com/repos/{REPOSITORY_NAME}' + response = requests.get(github_api_url, headers=GITHUB_HEADERS) + data = response.json() + return data["default_branch"] + + +def get_push_event_details() -> dict: + """ + Get the details of the GitHub push event from the API. + + This function will get the details of the GitHub push event from the API. + + Returns + ------- + dict + Dictionary containing the details of the push event. + """ + github_api_url = f'https://api.github.com/repos/{REPOSITORY_NAME}/events' + + # query parameters + params = { + "per_page": 100 + } + + response = requests.get(github_api_url, headers=GITHUB_HEADERS, params=params) + # print(response.json()) + push_event = None + for event in response.json(): + if event["type"] == "PushEvent" and \ + event["payload"]["ref"] == f"refs/heads/{get_repo_default_branch()}" and \ + event["payload"]["head"] == os.environ["GITHUB_SHA"]: + push_event = event + break + + if push_event is None: + msg = ":exclamation: ERROR: Push event not found in the GitHub API." + append_github_step_summary(message=msg) + if os.getenv('INPUT_FAIL_ON_EVENTS_API_ERROR', 'false').lower() == 'true': + raise SystemExit(msg) + + # use regex and convert created at to yyyy.m.d + match = re.search(r'(\d{4})-(\d{1,2})-(\d{1,2})', push_event["created_at"]) + + release_version = None + if match: + year = match.group(1) + month = match.group(2).zfill(2) # Ensure month is zero-padded to two digits + day = match.group(3).zfill(2) # Ensure day is zero-padded to two digits + release_version = f"{year}.{month}.{day}" + + push_event_details = dict( + release_version=release_version, + release_build=push_event["payload"]["head"][0:7], + ) + return push_event_details + + +def parse_changelog(changelog_path: str) -> dict: + """ + Parse the changelog file. + + This function will parse the changelog and return a dictionary. + + Parameters + ---------- + changelog_path : str + Full path to the changelog file. + + Returns + ------- + dict + Dictionary containing the following keys: + + - version + - date + - changes + - url + """ + with open(changelog_path, 'r') as file: + changelog_content = file.read() + + # Define regular expressions to match version headers and their content + version_pattern = r'\[(\d+\.\d+\.\d+)\] - (\d{4}-\d{2}-\d{2})' + url_pattern = r'\[(\d+\.\d+\.\d+)\]:\s+(https:\/\/\S+)' + + # Find all version headers and their content + versions = re.findall(version_pattern, changelog_content) + urls = re.findall(url_pattern, changelog_content) + + # Determine the newest version based on the version numbers + newest_version = max(versions, key=lambda x: tuple(map(int, x[0].split('.')))) + + # Find the URL associated with the newest version + newest_version_url = None + for version, url in urls: + if version == newest_version[0]: + newest_version_url = url + break + + # Extract the changes for the newest version + newest_version_changes = "" + in_newest_version_section = False + for version, date in versions: + if version == newest_version[0]: + in_newest_version_section = True + elif in_newest_version_section and version != newest_version[0]: + break + if in_newest_version_section: + version_start = changelog_content.find(f'[{version}] - {date}') + next_version = versions.index((version, date)) + 1 + if next_version < len(versions): + version_end = changelog_content.find(f'\n## [{versions[next_version][0]}] - {versions[next_version][1]}', version_start) + else: + version_end = len(changelog_content) + + # Extract changes while excluding the start of the next version + if version_end != -1: + newest_version_changes = changelog_content[version_start:version_end] + else: + newest_version_changes = changelog_content[version_start:] + + # Remove the version header line from the changes + newest_version_changes = newest_version_changes.replace(f'[{newest_version[0]}] - {newest_version[1]}\n', '') + + # Remove the URL line from the changes + if newest_version_url: + newest_version_changes = newest_version_changes.replace(f'[{newest_version[0]}]: {newest_version_url}\n', '') + + # Create a dictionary with the extracted information + changelog_data = { + 'version': newest_version[0], + 'date': newest_version[1], + 'url': newest_version_url, + 'changes': newest_version_changes.strip() + } + + return changelog_data + + +def main() -> dict: + """ + Main function for the action. + + Returns + ------- + dict + Job outputs. + """ + job_outputs = dict() + + # Get the inputs from the Environment File + changelog_path = os.path.join(os.getcwd(), "github", "workspace", os.environ["INPUT_CHANGELOG_PATH"]) + + # Check if the changelog exists + changelog_exists = check_if_changelog_exists(changelog_path=changelog_path) + job_outputs["changelog_exists"] = str(changelog_exists) + + # Get the push event details + push_event_details = get_push_event_details() + + changelog_data = None + release_exists = False + # Parse the changelog + if changelog_exists: + changelog_data = parse_changelog(changelog_path=changelog_path) + job_outputs['changelog_changes'] = changelog_data["changes"] + job_outputs['changelog_date'] = changelog_data["date"] + job_outputs['changelog_url'] = changelog_data["url"] + job_outputs['changelog_version'] = changelog_data["version"] + + # Check if the release exists + release_exists = check_release(version=changelog_data["version"]) + else: + job_outputs['changelog_changes'] = '' + job_outputs['changelog_date'] = '' + job_outputs['changelog_url'] = '' + job_outputs['changelog_version'] = '' + + job_outputs['changelog_release_exists'] = str(release_exists) + job_outputs['publish_stable_release'] = str(not release_exists) + + if release_exists: + # the changelog release exists, so we want to publish a pre-release instead + append_github_step_summary( + message=":warning: WARNING: The release in the changelog already exists. Defaulting to a pre-release.") + release_version = push_event_details["release_version"] + release_build = push_event_details["release_build"] + release_tag = f"v{release_version}-{release_build}" + else: + # the changelog release does not exist, so we want to publish a stable release + release_version = changelog_data["version"] + release_build = push_event_details["release_build"] + release_tag = f"v{release_version}" + + job_outputs['release_version'] = release_version + job_outputs['release_build'] = release_build + job_outputs['release_tag'] = release_tag + + # Set the outputs + for output_name, output_value in job_outputs.items(): + set_github_action_output(output_name=output_name, output_value=output_value) + + return job_outputs + + +if __name__ == "__main__": + main() diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..c9d3a1a --- /dev/null +++ b/codecov.yml @@ -0,0 +1,15 @@ +--- +codecov: + branch: master + +coverage: + status: + project: + default: + target: auto + threshold: 10% + +comment: + layout: "diff, flags, files" + behavior: default + require_changes: false # if true: only post the comment if coverage changes diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..4220a11 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,2 @@ +pytest==7.4.2 +pytest-cov==4.1.0 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8a5f24f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +python-dotenv==1.0.0 +requests==2.31.0 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..edbbeab --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,124 @@ +# standard imports +import os +import shutil + +# lib imports +from dotenv import load_dotenv +import pytest +import requests + +# set environment variables +load_dotenv() +os.environ['GITHUB_REPOSITORY'] = 'LizardByte/action-setup-release' +os.environ['GITHUB_SHA'] = '1234567890abcdef1234567890abcdef12345678' +os.environ['GITHUB_OUTPUT'] = 'github_output.md' +os.environ['GITHUB_STEP_SUMMARY'] = 'github_step_summary.md' +os.environ['INPUT_CHANGELOG_PATH'] = 'CHANGELOG.md' + +try: + GITHUB_TOKEN = os.environ['INPUT_GITHUB_TOKEN'] +except KeyError: + GITHUB_TOKEN = os.environ['INPUT_GITHUB_TOKEN'] = '' + +GITHUB_HEADERS = {'Authorization': f'token {GITHUB_TOKEN}'} + + +def pytest_runtest_setup(item): + if 'github_token' in item.fixturenames and not GITHUB_TOKEN: + pytest.skip('INPUT_GITHUB_TOKEN environment variable not set') + + +@pytest.fixture(scope='session') +def github_token(): + yield + + +@pytest.fixture(scope='function') +def github_output_file(): + f = os.environ['GITHUB_OUTPUT'] + + # touch the file + with open(f, 'w') as fi: + fi.write('') + + yield f + + # re-touch the file + with open(f, 'w') as fi: + fi.write('') + + +@pytest.fixture(scope='function') +def github_step_summary_file(): + f = os.environ['GITHUB_STEP_SUMMARY'] + + # touch the file + with open(f, 'w') as fi: + fi.write('') + + yield f + + # re-touch the file + with open(f, 'w') as fi: + fi.write('') + + +@pytest.fixture(scope='function', params=[0, 1]) +def changelog_set(request): + change_set = request.param + + # get set directory + set_dir = os.path.join(os.getcwd(), 'tests', 'data', f'set{change_set}') + + # workspace directory + workspace_dir = os.path.join(os.getcwd(), 'github', 'workspace') + + # copy the changelog to `github/workspace` + os.makedirs(workspace_dir, exist_ok=True) + shutil.copyfile( + src=os.path.join(set_dir, 'CHANGELOG.md'), + dst=os.path.join(workspace_dir, 'CHANGELOG.md') + ) + + # read the version from the version.txt file + with open(os.path.join(set_dir, 'version.txt'), 'r') as f: + version = f.read().strip() + + # read the date from the date.txt file + with open(os.path.join(set_dir, 'date.txt'), 'r') as f: + date = f.read().strip() + + # read the url from the url.txt file + with open(os.path.join(set_dir, 'url.txt'), 'r') as f: + url = f.read().strip() + + # read the changes from the changes.txt file + with open(os.path.join(set_dir, 'changes.txt'), 'r') as f: + changes = f.read().strip() + + fixture = dict( + changelog_path=os.path.join(workspace_dir, 'CHANGELOG.md'), + version=version, + date=date, + url=url, + changes=changes, + ) + + yield fixture + + # clean the workspace + shutil.rmtree(workspace_dir) + + +@pytest.fixture(scope='session') +def latest_commit(github_token): + # get commits on the default branch + github_api_url = f"https://api.github.com/repos/{os.environ['GITHUB_REPOSITORY']}/commits" + response = requests.get( + url=github_api_url, + headers=GITHUB_HEADERS, + params={'sha': 'master'}, + ) + data = response.json() + commit = data[0]['sha'] + return commit diff --git a/tests/data/set0/CHANGELOG.md b/tests/data/set0/CHANGELOG.md new file mode 100644 index 0000000..d6f5efb --- /dev/null +++ b/tests/data/set0/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## [0.1.0] - 1970-01-01 +**Initial Release** + +[0.1.0]: https://github.com/octocat/Hello-World/releases/tag/v0.1.0 diff --git a/tests/data/set0/changes.txt b/tests/data/set0/changes.txt new file mode 100644 index 0000000..484299f --- /dev/null +++ b/tests/data/set0/changes.txt @@ -0,0 +1 @@ +**Initial Release** diff --git a/tests/data/set0/date.txt b/tests/data/set0/date.txt new file mode 100644 index 0000000..3478548 --- /dev/null +++ b/tests/data/set0/date.txt @@ -0,0 +1 @@ +1970-01-01 diff --git a/tests/data/set0/url.txt b/tests/data/set0/url.txt new file mode 100644 index 0000000..56616dc --- /dev/null +++ b/tests/data/set0/url.txt @@ -0,0 +1 @@ +https://github.com/octocat/Hello-World/releases/tag/v0.1.0 diff --git a/tests/data/set0/version.txt b/tests/data/set0/version.txt new file mode 100644 index 0000000..6e8bf73 --- /dev/null +++ b/tests/data/set0/version.txt @@ -0,0 +1 @@ +0.1.0 diff --git a/tests/data/set1/CHANGELOG.md b/tests/data/set1/CHANGELOG.md new file mode 100644 index 0000000..419e160 --- /dev/null +++ b/tests/data/set1/CHANGELOG.md @@ -0,0 +1,492 @@ +# Changelog + +## [0.20.0] - 2023-05-28 +**Breaking** +- (Windows) The Windows installer version of Sunshine is now always launched by the Sunshine Service. Manually launching Sunshine.exe from Program Files is no longer supported. This was necessary to address security issues caused by non-admin users having access to Sunshine's config data. If you have set up Task Scheduler or other mechanisms to launch Sunshine automatically, remove those from your system before updating. +- (Windows) The Start Menu shortcut has been redesigned for use with the Sunshine Service. It now launches Sunshine in the background (if not already running) and opens the Web UI, avoiding the persistent Command Prompt window present in prior versions. The Start Menu shortcut is now the recommended method for opening the Web UI and launching Sunshine. +- (Network/UPnP) If the Moonlight Internet Hosting Tool is installed alongside Sunshine, you must remove it or upgrade to v5.6 or later to prevent conflicts with Sunshine's UPnP support. As a reminder, the Moonlight Internet Hosting Tool is not required to stream over the Internet with Sunshine. Instead, simply enable UPnP in the Sunshine Web UI. +- (Windows) If Steam is installed, the Steam Streaming Speakers driver will be automatically installed when starting a stream for the first time. This behavior can be disabled in the Audio/Video tab of the Web UI. This Steam driver enables support for surround sound and muting host audio without requiring any manual configuration. +- (Input) The Back Button Timeout option has been renamed to Guide Button Emulation Timeout and has been disabled by default to ensure long presses on the Back button work by default. The previous behavior can be restored by setting the Guide Button Emulation Timeout to 2000. +- (Windows) The service name of SunshineSvc has been changed to SunshineService to address a false positive in MalwareBytes. If you have any scripts or other logic on your system that is using the service name, you will need to update that for the new name. +- (Windows) To support new installer features, install-service.bat no longer sets the service to auto-start by default. Users executing install-service.bat manually on the Sunshine portable build must also execute autostart-service.bat to start Sunshine on boot. However, installing the service manually like this is not recommended. Instead, use the Sunshine installer which handles service installation and configuration automatically. +- (Linux/Fedora) Fedora 36 builds are removed due to upstream end of support + +**Added** +- (Windows) Added an option to launch apps and prep/undo commands as administrator +- (Installer/Windows) Added an option to choose whether Sunshine launches on boot. If not configured to launch on boot, use the Start Menu shortcut to start Sunshine when desired. +- (Input/Windows) Added option to send VK codes instead of scancodes for compatibility with iOS/Android devices using non-English keyboard layouts +- (UI) The Apply/Restart option is now available in the Web UI for all platforms +- (Systray) Added a Restart option to the system tray context menu +- (Video/Windows) Added host latency data to video frames. This requires future updates to Moonlight to display in the on-screen overlay. +- (Audio) Added support for matching Audio Sink and Virtual Sink values on device names +- (Client) Added friendly error messages for clients when streaming fails to start +- (Video/Windows) Added warning log messages when Windows is hiding DRM-protected content from display capture +- (Interop/Windows) Added warning log messages when GeForce Experience is currently using the same ports as Sunshine +- (Linux/Fedora) Fedora 38 builds are now available + +**Changed** +- (Video) Encoder selection now happens at each stream start for more reliable GPU detection +- (Video/Windows) The host display now stays on while clients are actively streaming +- (Audio) Streaming will no longer fail if audio capture is unavailable +- (Audio/Windows) Sunshine will automatically switch back to the Virtual Sink if the default audio device is changed while streaming +- (Audio) Changes to the host audio playback option will now take effect when resuming a session from Moonlight +- (Audio/Windows) Sunshine will switch to a different default audio device if Steam Streaming Speakers are the default when Sunshine starts. This handles cases where Sunshine terminates unexpectedly without restoring the default audio device. +- (Apps) The Connection Terminated dialog will no longer appear in Moonlight when the app on the host exits normally +- (Systray/Windows) Quitting Sunshine via the system tray will now stop the Sunshine Service rather than leaving it running and allowing it to restart Sunshine +- (UI) The 100.64.0.0/10 CGN IP address range is now treated as a LAN address range +- (Video) Removed a workaround for some versions of Moonlight prior to mid-2022 +- (UI) The PIN field is now cleared after successfully pairing +- (UI) User names are now treated as case-insensitive +- (Linux) Changed udev rule to automatically grant access to virtual input devices +- (UI) Several item descriptions were adjusted to reflect newer configuration recommendations +- (UI) Placeholder text opacity has been reduced to improve contrast with non-placeholder text +- (Video/Windows) Minor capture performance improvements + +**Fixed** +- (Video) VRAM usage while streaming is significantly reduced, particularly with higher display resolutions and HDR +- (Network/UPnP) UPnP support was rewritten to fix several major issues handling router restarts, IP address changes, and port forwarding expiration +- (Input) Fixed modifier keys from the software keyboard on Android clients +- (Audio) Fixed handling of default audio device changes while streaming +- (Windows) Fixed streaming after Microsoft Remote Desktop or Fast User Switching has been used +- (Input) Fixed some games not recognizing emulated Guide button presses +- (Video/Windows) Fixed incorrect gamma when using an Advanced Color SDR display on the host +- (Installer/Windows) The installer is no longer blurry on High DPI systems +- (Systray/Windows) Fixed multiple system tray icons appearing if Sunshine exits unexpectedly +- (Systray/Windows) Fixed the system tray icon not appearing in several situations +- (Windows) Fixed hang on shutdown/restart if mDNS registration fails +- (UI) Fixed missing response headers +- (Stability) Fixed several possible crashes in cases where the client did not successfully connect +- (Stability) Fixed several memory leaks +- (Input/Windows) Back/Select input now correctly generates the Share button when emulating DS4 controllers +- (Audio/Windows) Fixed various bugs in audio-info.exe that led to inaccurate output on some systems +- (Video/Windows) Fixed incorrect resolution values from dxgi-info.exe on High DPI systems +- (Video/Linux) Fixed poor quality encoding from H.264 on Intel encoders +- (Config) Fixed a couple of typos in predefined resolutions + +**Dependencies** +- Bump sphinx-copybutton from 0.5.1 to 0.5.2 +- Bump sphinx from 6.13 to 7.0.1 +- Bump third-party/nv-codec-headers from 2055784 to 2cd175b +- Bump furo from 2023.3.27 to 2023.5.20 + +**Misc** +- (Build/Linux) Add X11 to PLATFORM_LIBARIES when found +- (Build/macOS) Fix compilation with Clang 14 +- (Docs) Fix nvlax URL +- (Docs) Add diagrams using graphviz +- (Docs) Improvements to source code documentation +- (Build) Unpin docker dependencies +- (Build/Linux) Honor install prefix for tray icon +- (Build/Windows) Unstripped binaries are now provided as a debuginfo package to support crash dump debugging +- (Config) Config directories are now created recursively + +## [0.19.1] - 2023-03-30 +**Fixed** +- (Audio) Fixed no audio issue introduced in v0.19.0 + +## [0.19.0] - 2023-03-29 +**Breaking** +- (Linux/Flatpak) Moved Flatpak to org.freedesktop.Platform 22.08 and Cuda 12.0.0 + This will drop support for Nvidia GPUs with compute capability 3.5 + +**Added** +- (Input) Added option to suppress input from gamepads, keyboards, or mice +- (Input/Linux) Added unicode support for remote pasting (may not work on all DEs) +- (Input/Linux) Added XTest input fallback +- (UI) Added version notifications to web UI +- (Linux/Windows) Add system tray icon +- (Windows) Added ability to safely elevate commands that fail due to insufficient permissions when running as a service +- (Config) Added global prep commands, and ability to exclude an app from using global prep commands +- (Installer/Windows) Automatically install ViGEmBus if selected + +**Changed** +- (Logging) Changed client verified messages to debug to prevent spamming the log +- (Config) Only save non default config values +- (Service/Linux) Use xdg-desktop-autostart for systemd service +- (Linux) Added config option to force capture method +- (Windows) Execute prep command in context of current user +- (Linux) Allow disconnected X11 outputs + +**Fixed** +- (Input/Windows) Fix issue where internation keys were not translated correct, and modifier keys appeared stuck +- (Linux) Fixed startup when /dev/dri didn't exist +- (UI) Changes software encoding settings to select menu instead of text input +- (Initialization) Do not terminate upon failure, allowing access to the web UI + +**Dependencies** +- Bump third-party/moonlight-common-c from 07beb0f to c9426a6 +- Bump babel from 2.11.0 to 2.12.1 +- Bump @fortawesome/fontawesome-free from 6.2.1 to 6.4.0 +- Bump third-party/ViGEmClient from 9e842ba to 726404e +- Bump ffmpeg +- Bump third-party/miniupnp from 014c9df to e439318 +- Bump furo from 2022.12.7 to 2023.3.27 +- Bump third-party/nanors from 395e5ad to e9e242e + +**Misc** +- (GitHub) Shared feature request board with Moonlight +- (Docs) Improved application examples +- (Docs) Added WIP documentation for source code using Doxygen and Breathe +- (Build) Fix linux clang build errors +- (Build/Archlinux) Skip irrelevant submodules +- (Build/Archlinux) Disable download timeout +- (Build/macOS) Support compiling for earlier releases of macOS +- (Docs) Add favicon +- (Docs) Add missing config default values +- (Build) Fix compiler warnings due to depreciated elements in C++17 +- (Build) Fix libcurl link errors +- (Clang) Adjusted formatting rules + +## [0.18.4] - 2023-02-20 +**Fixed** +- (Linux/AUR) Drop support of AUR package +- (Docker) General enhancements to docker images + +## [0.18.3] - 2023-02-13 +**Added** +- (Linux) Added PKGBUILD for Archlinux based distros to releases +- (Linux) Added precompiled package for Archlinux based distros to releases +- (Docker) Added archlinux docker image (x86_64 only) + +## [0.18.2] - 2023-02-13 +**Fixed** +- (Video/KMV/Linux) Fixed wayland capture on Nvidia for KMS +- (Video/Linux) Implement vaSyncBuffer stuf for libva <2.9.0 +- (UI) Fix issue where mime type was not being set for node_modules when using a reverse proxy +- (UI/macOS) Added missing audio sink config options +- (Linux) Specify correct Boost dependency versions +- (Video/AMF) Add missing encoder tunables + +## [0.18.1] - 2023-01-31 +**Fixed** +- (Linux) Fixed missing dependencies for deb and rpm packages +- (Linux) Use dynamic boost + +## [0.18.0] - 2023-01-29 +Attention, this release contains critical security fixes. Please update as soon as possible. Additionally, we are +encouraging users to change your Sunshine password, especially if you expose the web UI (i.e. port 47790 by default) +to the internet, or have ever uploaded your logs with verbose output to a public resource. + +**Added** +- (Windows) Add support for Intel QuickSync +- (Linux) Added aarch64 deb and rpm packages +- (Windows) Add support for hybrid graphics systems, such as laptops with both integrated and discrete GPUs +- (Linux) Add support for streaming from Steam Deck Gaming Mode +- (Windows) Add HDR support, see https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/usage.html#hdr-support + +**Fixed** +- (Network) Refactor code for UPnP port forwarding +- (Video) Enforce 10 FPS encoding frame rate minimum to improve static image quality +- (Linux) deb and rpm packages are now specific to destination distro and version +- (Docs) Add nvidia/nvenc preset migration guide +- (Network) Performance optimizations +- (Video/Windows) Fix streaming to multiple clients from hardware encoder +- (Linux) Fix child process spawning +- (Security) Fix security vulnerability in implementation of SimpleWebServer +- (Misc) Rename "Steam BigPicture" to "Steam Big Picture" in default apps.json +- (Security) Scrub basic authorization header from logs +- (Linux) The systemd service will now restart in the event of a crash +- (Video/KMS/Linux) Fixed error: `couldn't import RGB Image: 00003002 and 00003004` +- (Video/Windows) Fix stream freezing triggered by the resolution changed +- (Installer/Windows) Fixes silent installation and other miscellaneous improvements +- (CPU) Significantly improved CPU usage + +## [0.17.0] - 2023-01-08 +If you are running Sunshine as a service on Windows, we are strongly urging you to update to v0.17.0 as soon as +possible. Older Windows versions of Sunshine had a security flaw in which the binary was located in a user-writable +location which is problematic when running as a service or on a multi-user system. Additionally, when running Sunshine +as a service, games and applications were launched as SYSTEM. This could lead to issues with save files and other game +settings. In v0.17.0, games now run under your user account without elevated privileges. + +**Breaking** +- (Apps) Removed automatic desktop entry (Re-add by adding an empty application named "Desktop" with no commands, "desktop.png" can be added as the image.) +- (Windows) Improved user upgrade experience (Suggest to manually uninstall existing Sunshine version before this upgrade. Do NOT select to remove everything, if prompted. Make a backup of config files before uninstall.) +- (Windows) Move config files to specific directory (files will be migrated automatically if using Windows installer) +- (Dependencies) Fix npm path (breaking change for package maintainers) + +**Added** +- (macOS) Added initial support for arm64 on macOS through Macports portfile +- (Input) Added support for foreign keyboard input +- (Misc) Logs inside the WebUI and log to file +- (UI/Windows) Added an Apply button to configuration page when running as a service +- (Input/Windows) Enable Mouse Keys while streaming for systems with no physical mouse + +**Fixed** +- (Video) Improved capture performance +- (Audio) Improved audio bitrate and quality handling +- (Apps/Windows) Fixed PATH environment variable handling +- (Apps/Windows) Use the proper environment variable for the Program Files (x86) folder +- (Service/Windows) Fix SunshineSvc hanging if an error occurs during startup +- (Service/Windows) Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies +- (Video) windows/vram: fix fringing in NV12 colour conversion +- (Apps/Windows) Launch games under the correct user account +- (Video) nvenc, amdvce: rework all user presets/options +- (Network) Generate certificates with unique serial numbers +- (Service/Windows) Graceful termination on shutdown, logoff, and service stop +- (Apps/Windows) Fix launching apps when Sunshine is running as admin +- (Misc) Remove/fix calls to std::abort() +- (Misc) Remove prompt to press enter after Sunshine exits +- (Misc) Make log priority consistent for execution messages +- (Apps) Applications in Moonlight clients are now updated automatically after editing +- (Video/Linux) Fix wayland capture on nvidia +- (Audio) Fix 7.1 surround channel mapping +- (Video) Fix NVENC profile values not applying +- (Network) Fix origin_web_ui_allowed binding +- (Service/Windows) Self terminate/restart service if process hangs for 10 seconds +- (Input/Windows) Fix Windows masked cursor blending with GPU encoders +- (Video) Color conversion fixes and BT.2020 support + +**Dependencies** +- Bump ffmpeg from 4.4 to 5.1 +- ffmpeg_patches: add amfenc delay/buffering fix +- CBS moved to ffmpeg submodules +- Migrate to upstream Simple-Web-Server submodule +- Bump third-party/TPCircularBuffer from `bce9170` to `8833b3a` +- Bump third-party/moonlight-common-c from `8169a31` to `ef9ad52` +- Bump third-party/miniupnp from `6f848ae` to `207cf44` +- Bump third-party/ViGEmClient from `f719a1d` to `9e842ba` +- Bump bootstrap from 5.0.0 to 5.2.3 +- Bump @fortawesome/fontawesome-free from 6.2.0 to 6.2.1 + +## [0.16.0] - 2022-12-13 +**Added** +- Add cover finder +- (Docker) Add arm64 docker image +- (Flatpak) Add installation helper scripts +- (Windows) Add support for Unicode input messages + +**Fixed** +- (Linux) Reintroduce Ubuntu 20.04 and 22.04 specific deb packages +- (Linux) Fixed udev and systemd file locations + +**Dependencies** +- Bump babel from 2.10.3 to 2.11.0 +- Bump sphinx-copybutton from 0.5.0 to 0.5.1 +- Bump KSXGitHub/github-actions-deploy-aur from 2.5.0 to 2.6.0 +- Use npm for web dependencies (breaking change for third-party package maintainers) +- Update moonlight-common-c +- Use pre-built ffmpeg from LizardByte/build-deps for all sunshine builds (breaking change for third-party package maintainers) +- Bump furo from 2022.9.29 to 2022.12.7 + +**Misc** +- Misc org level workflow updates +- Fix misc typos in docs +- Fix winget release + +## [0.15.0] - 2022-10-30 +**Added** +- (Windows) Add firewall rules scripts +- (Windows) Automatically add and remove firewall rules at install/uninstall +- (Windows) Automatically add and remove service at install/uninstall +- (Docker) Official image added +- (Linux) Add aarch64 flatpak package + +**Changed** +- (Windows/Linux/MacOS) - Move default config and apps file to assets directory +- (MacOS) Bump boost to 1.80 for macport builds +- (Linux) Remove backup and restore of config files + +**Fixed** +- (Linux) - Create sunshine config directory if it doesn't exist +- (Linux) Remove portable home and config directories for AppImage +- (Windows) Include service install and uninstall scripts again +- (Windows) Automatically delete start menu entry upon uninstall +- (Windows) Automatically delete program install directory upon uninstall, with user prompt +- (Linux) Handle the case of no default audio sink +- (Windows/Linux/MacOS) Fix default image paths +- (Linux) Fix CUDA RGBA to NV12 conversion + +## [0.14.1] - 2022-08-09 +**Added** +- (Linux) Flatpak package added +- (Linux) AUR package automated updates +- (Windows) Winget package automated updates + +**Changed** +- (General) Moved repo to @LizardByte GitHub org +- (WebUI) Fixed button spacing on home page +- (WebUI) Added Discord WidgetBot Crate + +**Fixed** +- (Linux/Mac) Default config and app files now copied to user home directory +- (Windows) Default config and app files now copied to working directory + +## [0.14.0] - 2022-06-15 + +**Added** +- (Documentation) Added Sphinx documentation available at https://sunshinestream.readthedocs.io/en/latest/ +- (Development) Initial support for Localization +- (Linux) Add rpm package as release asset +- (macOS) Add Portfile as release asset +- (Windows) Add DwmFlush() call to improve capture +- (Windows) Add Windows installer + +**Fixed** +- (AMD) Fixed hwdevice being destroyed before context +- (Linux) Added missing dependencies to AppImage +- (Linux) Fixed rumble events causing game to freeze +- (Linux) Improved Pulse/Pipewire compatibility +- (Linux) Moved to single deb package +- (macOS) Fixed missing TPCircularBuffer submodule +- (Stream) Properly catch exceptions in stream broadcast handlers +- (Stream/Video) AVPacket fix + +## [0.13.0] - 2022-02-27 +**Added** +- (macOS) Initial support for macOS (#40) + +## [0.12.0] - 2022-02-13 +**Added** +- New command line argument `--version` +- Custom png poster support + +**Changed** +- Correct software bitrate calculation +- Increase vbv-bufsize to 1/10 of requested bitrate +- Improvements to Web UI + +## [0.11.1] - 2021-10-04 +**Changed** +- (Linux) Fix search path for config file and assets + +## [0.11.0] - 2021-10-04 +**Added** +- (Linux) Added support for wlroots based compositors on Wayland. +- (Windows) Added an icon for the executable + +**Changed** +- Fixed a bug causing segfault when connecting multiple controllers. +- (Linux) Improved NVENC, it now offloads converting images from RGB to NV12 +- (Linux) Fixed a bug causes stuttering + +## [0.10.1] - 2021-08-21 +**Changed** +- (Linux) Re-enabled KMS + +## [0.10.0] - 2021-08-20 +**Added** +- Added support for Rumble with gamepads. +- Added support for keyboard shortcuts <--- See the README for details. +- (Windows) A very basic script has been added in Sunshine-Windows\tools <-- This will start Sunshine at boot with the highest privileges which is needed to display the login prompt. + +**Changed** +- Some cosmetic changes to the WebUI. +- The first time the WebUI is opened, it will request the creation of a username/password pair from the user. +- Fixed audio crackling introduced in version 0.8.0 +- (Linux) VAAPI hardware encoding now works on Intel i7-6700 at least. <-- For the best experience, using ffmpeg version 4.3 or higher is recommended. +- (Windows) Installing from debian package shouldn't overwrite your configuration files anymore. <-- It's recommended that you back up `/etc/sunshine/` before testing this. + +## [0.9.0] - 2021-07-11 +**Added** +- Added audio encryption +- (Linux) Added basic NVENC support on Linux +- (Windows) The Windows version can now capture the lock screen and the UAC prompt as long as it's run through `PsExec.exe` https://docs.microsoft.com/en-us/sysinternals/downloads/psexec + +**Changed** +- Sunshine will now accept expired or not-yet-valid certificates, as long as they are signed properly. +- Fixed compatibility with iOS version of Moonlight +- Drastically reduced chance of being forced to skip error correction due to video frame size +- (Linux) sunshine.service will be installed automatically. + +## [0.8.0] - 2021-06-30 +**Added** +- Added mDNS support: Moonlight will automatically find Sunshine. +- Added UPnP support. It's off by default. + +## [0.7.7] - 2021-06-24 +**Added** +- (Linux) Added installation package for Debian + +**Changed** +- Fixed incorrect scaling for absolute mouse coordinates when using multiple monitors. +- Fixed incorrect colors when scaling for software encoder + +## [0.7.1] - 2021-06-18 +**Changed** +- (Linux) Fixed an issue where it was impossible to start sunshine on ubuntu 20.04 + +## [0.7.0] - 2021-06-16 +**Added** +- Added a Web Manager. Accessible through: https://localhost:47990 or https://:47990 +- (Linux) Added hardware encoding support for AMD on Linux + +**Changed** +- (Linux) Moved certificates and saved pairings generated during runtime to .config/sunshine on Linux + +## [0.6.0] - 2021-05-26 +**Added** +- Added support for surround audio + +**Changed** +- Maintain aspect ratio when scaling video +- Fix issue where Sunshine is forced to drop frames when they are too large + +## [0.5.0] - 2021-05-13 +**Added** +- Added support for absolute mouse coordinates +- (Linux) Added support for streaming specific monitor on Linux +- (Windows) Added support for AMF on Windows + +## [0.4.0] - 2020-05-03 +**Changed** +- prep-cmd is now optional in apps.json +- Fixed bug causing video artifacts +- Fixed bug preventing Moonlight from closing app on exit +- Fixed bug causing preventing keyboard keys from repeating on latest version of Moonlight +- Fixed bug causing segfault when another session of sunshine was already running +- Fixed bug causing crash when monitor has resolution 1366x768 + +## [0.3.1] - 2020-04-24 +**Changed** +- Fix a memory leak. + +## [0.3.0] - 2020-04-23 +**Changed** +- Hardware acceleration on NVidia GPU's for Video encoding on Windows + +## [0.2.0] - 2020-03-21 +**Changed** +- Multicasting is now supported: You can set the maximum simultaneous connections with the configurable option: channels +- Configuration variables can be overwritten on the command line: "name=value" --> it can be useful to set min_log_level=debug without modifying the configuration file +- Switches to make testing the pairing mechanism more convenient has been added, see "sunshine --help" for details + +## [0.1.1] - 2020-01-30 +**Added** +- (Linux) Added deb package and service for Linux + +## [0.1.0] - 2020-01-27 +**Added** +- The first official release for Sunshine! + +[0.1.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.1.0 +[0.1.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.1.1 +[0.2.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.2.0 +[0.3.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.3.0 +[0.3.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.3.1 +[0.4.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.4.0 +[0.5.0]: https://github.com/LizardByte/Sunshine/releases/tag/0.5.0 +[0.6.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.6.0 +[0.7.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.0 +[0.7.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.1 +[0.7.7]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.7 +[0.8.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.8.0 +[0.9.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.9.0 +[0.10.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.10.0 +[0.10.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.10.1 +[0.11.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.11.0 +[0.11.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.11.1 +[0.12.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.12.0 +[0.13.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.13.0 +[0.14.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.14.0 +[0.14.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.14.1 +[0.15.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.15.0 +[0.16.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.16.0 +[0.17.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.17.0 +[0.18.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.0 +[0.18.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.1 +[0.18.2]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.2 +[0.18.3]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.3 +[0.18.4]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.4 +[0.19.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.19.0 +[0.19.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.19.1 +[0.20.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.20.0 diff --git a/tests/data/set1/changes.txt b/tests/data/set1/changes.txt new file mode 100644 index 0000000..cf47fe9 --- /dev/null +++ b/tests/data/set1/changes.txt @@ -0,0 +1,78 @@ +**Breaking** +- (Windows) The Windows installer version of Sunshine is now always launched by the Sunshine Service. Manually launching Sunshine.exe from Program Files is no longer supported. This was necessary to address security issues caused by non-admin users having access to Sunshine's config data. If you have set up Task Scheduler or other mechanisms to launch Sunshine automatically, remove those from your system before updating. +- (Windows) The Start Menu shortcut has been redesigned for use with the Sunshine Service. It now launches Sunshine in the background (if not already running) and opens the Web UI, avoiding the persistent Command Prompt window present in prior versions. The Start Menu shortcut is now the recommended method for opening the Web UI and launching Sunshine. +- (Network/UPnP) If the Moonlight Internet Hosting Tool is installed alongside Sunshine, you must remove it or upgrade to v5.6 or later to prevent conflicts with Sunshine's UPnP support. As a reminder, the Moonlight Internet Hosting Tool is not required to stream over the Internet with Sunshine. Instead, simply enable UPnP in the Sunshine Web UI. +- (Windows) If Steam is installed, the Steam Streaming Speakers driver will be automatically installed when starting a stream for the first time. This behavior can be disabled in the Audio/Video tab of the Web UI. This Steam driver enables support for surround sound and muting host audio without requiring any manual configuration. +- (Input) The Back Button Timeout option has been renamed to Guide Button Emulation Timeout and has been disabled by default to ensure long presses on the Back button work by default. The previous behavior can be restored by setting the Guide Button Emulation Timeout to 2000. +- (Windows) The service name of SunshineSvc has been changed to SunshineService to address a false positive in MalwareBytes. If you have any scripts or other logic on your system that is using the service name, you will need to update that for the new name. +- (Windows) To support new installer features, install-service.bat no longer sets the service to auto-start by default. Users executing install-service.bat manually on the Sunshine portable build must also execute autostart-service.bat to start Sunshine on boot. However, installing the service manually like this is not recommended. Instead, use the Sunshine installer which handles service installation and configuration automatically. +- (Linux/Fedora) Fedora 36 builds are removed due to upstream end of support + +**Added** +- (Windows) Added an option to launch apps and prep/undo commands as administrator +- (Installer/Windows) Added an option to choose whether Sunshine launches on boot. If not configured to launch on boot, use the Start Menu shortcut to start Sunshine when desired. +- (Input/Windows) Added option to send VK codes instead of scancodes for compatibility with iOS/Android devices using non-English keyboard layouts +- (UI) The Apply/Restart option is now available in the Web UI for all platforms +- (Systray) Added a Restart option to the system tray context menu +- (Video/Windows) Added host latency data to video frames. This requires future updates to Moonlight to display in the on-screen overlay. +- (Audio) Added support for matching Audio Sink and Virtual Sink values on device names +- (Client) Added friendly error messages for clients when streaming fails to start +- (Video/Windows) Added warning log messages when Windows is hiding DRM-protected content from display capture +- (Interop/Windows) Added warning log messages when GeForce Experience is currently using the same ports as Sunshine +- (Linux/Fedora) Fedora 38 builds are now available + +**Changed** +- (Video) Encoder selection now happens at each stream start for more reliable GPU detection +- (Video/Windows) The host display now stays on while clients are actively streaming +- (Audio) Streaming will no longer fail if audio capture is unavailable +- (Audio/Windows) Sunshine will automatically switch back to the Virtual Sink if the default audio device is changed while streaming +- (Audio) Changes to the host audio playback option will now take effect when resuming a session from Moonlight +- (Audio/Windows) Sunshine will switch to a different default audio device if Steam Streaming Speakers are the default when Sunshine starts. This handles cases where Sunshine terminates unexpectedly without restoring the default audio device. +- (Apps) The Connection Terminated dialog will no longer appear in Moonlight when the app on the host exits normally +- (Systray/Windows) Quitting Sunshine via the system tray will now stop the Sunshine Service rather than leaving it running and allowing it to restart Sunshine +- (UI) The 100.64.0.0/10 CGN IP address range is now treated as a LAN address range +- (Video) Removed a workaround for some versions of Moonlight prior to mid-2022 +- (UI) The PIN field is now cleared after successfully pairing +- (UI) User names are now treated as case-insensitive +- (Linux) Changed udev rule to automatically grant access to virtual input devices +- (UI) Several item descriptions were adjusted to reflect newer configuration recommendations +- (UI) Placeholder text opacity has been reduced to improve contrast with non-placeholder text +- (Video/Windows) Minor capture performance improvements + +**Fixed** +- (Video) VRAM usage while streaming is significantly reduced, particularly with higher display resolutions and HDR +- (Network/UPnP) UPnP support was rewritten to fix several major issues handling router restarts, IP address changes, and port forwarding expiration +- (Input) Fixed modifier keys from the software keyboard on Android clients +- (Audio) Fixed handling of default audio device changes while streaming +- (Windows) Fixed streaming after Microsoft Remote Desktop or Fast User Switching has been used +- (Input) Fixed some games not recognizing emulated Guide button presses +- (Video/Windows) Fixed incorrect gamma when using an Advanced Color SDR display on the host +- (Installer/Windows) The installer is no longer blurry on High DPI systems +- (Systray/Windows) Fixed multiple system tray icons appearing if Sunshine exits unexpectedly +- (Systray/Windows) Fixed the system tray icon not appearing in several situations +- (Windows) Fixed hang on shutdown/restart if mDNS registration fails +- (UI) Fixed missing response headers +- (Stability) Fixed several possible crashes in cases where the client did not successfully connect +- (Stability) Fixed several memory leaks +- (Input/Windows) Back/Select input now correctly generates the Share button when emulating DS4 controllers +- (Audio/Windows) Fixed various bugs in audio-info.exe that led to inaccurate output on some systems +- (Video/Windows) Fixed incorrect resolution values from dxgi-info.exe on High DPI systems +- (Video/Linux) Fixed poor quality encoding from H.264 on Intel encoders +- (Config) Fixed a couple of typos in predefined resolutions + +**Dependencies** +- Bump sphinx-copybutton from 0.5.1 to 0.5.2 +- Bump sphinx from 6.13 to 7.0.1 +- Bump third-party/nv-codec-headers from 2055784 to 2cd175b +- Bump furo from 2023.3.27 to 2023.5.20 + +**Misc** +- (Build/Linux) Add X11 to PLATFORM_LIBARIES when found +- (Build/macOS) Fix compilation with Clang 14 +- (Docs) Fix nvlax URL +- (Docs) Add diagrams using graphviz +- (Docs) Improvements to source code documentation +- (Build) Unpin docker dependencies +- (Build/Linux) Honor install prefix for tray icon +- (Build/Windows) Unstripped binaries are now provided as a debuginfo package to support crash dump debugging +- (Config) Config directories are now created recursively diff --git a/tests/data/set1/date.txt b/tests/data/set1/date.txt new file mode 100644 index 0000000..6da27b1 --- /dev/null +++ b/tests/data/set1/date.txt @@ -0,0 +1 @@ +2023-05-28 diff --git a/tests/data/set1/url.txt b/tests/data/set1/url.txt new file mode 100644 index 0000000..df920f2 --- /dev/null +++ b/tests/data/set1/url.txt @@ -0,0 +1 @@ +https://github.com/LizardByte/Sunshine/releases/tag/v0.20.0 diff --git a/tests/data/set1/version.txt b/tests/data/set1/version.txt new file mode 100644 index 0000000..5a03fb7 --- /dev/null +++ b/tests/data/set1/version.txt @@ -0,0 +1 @@ +0.20.0 diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py new file mode 100644 index 0000000..f643500 --- /dev/null +++ b/tests/unit/test_main.py @@ -0,0 +1,71 @@ +# lib imports +import pytest + +# local imports +from action import main + + +@pytest.mark.parametrize('message', [ + 'foo', + 'bar', +]) +def test_append_github_step_summary(github_step_summary_file, message): + main.append_github_step_summary(message=message) + + with open(github_step_summary_file, 'r') as f: + output = f.read() + + assert output.endswith(f"{message}\n") + + +@pytest.mark.parametrize('outputs', [ + ('test_1', 'foo'), + ('test_2', 'bar'), +]) +def test_set_github_action_output(github_output_file, outputs): + main.set_github_action_output(output_name=outputs[0], output_value=outputs[1]) + + with open(github_output_file, 'r') as f: + output = f.read() + + assert output.endswith(f"{outputs[0]}={outputs[1]}\n") + + +def test_check_if_changelog_exists(changelog_set): + assert main.check_if_changelog_exists(changelog_path=changelog_set['changelog_path']) + + +@pytest.mark.parametrize('version', [ + ('1970.1.1', False), +]) +def test_check_release(version): + assert main.check_release(version=version[0]) == version[1] + + +def test_get_repo_default_branch(github_token): + assert main.get_repo_default_branch() == 'master' + + +@pytest.mark.xfail(reason='This test will until we have a push to `master`') +def test_get_push_event_details(latest_commit): + assert main.get_push_event_details() + + +def test_parse_changelog(changelog_set): + changelog_data = main.parse_changelog(changelog_path=changelog_set['changelog_path']) + + assert changelog_data['version'] == changelog_set['version'] + assert changelog_data['date'] == changelog_set['date'] + assert changelog_data['url'] == changelog_set['url'] + assert changelog_data['changes'] == changelog_set['changes'] + + +@pytest.mark.xfail(reason='This test will until we have a push to `master`') +def test_main(changelog_set, github_output_file, github_step_summary_file, github_token): + job_outputs = main.main() + + with open(github_output_file, 'r') as f: + output = f.read() + + for output_name, output_value in job_outputs.items(): + assert f'{output_name}={output_value}\n' in output