diff --git a/.github/scripts/lint.py b/.github/scripts/lint.py new file mode 100644 index 0000000..afebe3c --- /dev/null +++ b/.github/scripts/lint.py @@ -0,0 +1,67 @@ +import os +import re +import sys +import yaml +import requests + + +DIR = 'plugins' + +KEY_SET = set(['owner', 'name', 'branch', 'docs']) +ENV_FILE_REGEX = '.*-qiime2-.*-20[0-9][0-9]\.([1-9]|1[0-2])\.yml' +GITHUB_BASE_URL = "https://api.github.com" + +env_urls = [] + +GITHUB_TOKEN = sys.argv[1] +GITHUB_BASE_URL = 'https://api.github.com' + + +def lint(yml): + # Assert corrrect keys + assert set(yml.keys()) == KEY_SET + + # Get the docs URL assert 200 + response = requests.get(yml['docs']) + assert response.status_code == 200 + + # Put together the owner/name:branch + url = f'{GITHUB_BASE_URL}/repos/{yml['owner']}/{yml['name']}/contents/environment-files' + headers = { + 'Authorization': f'token: {GITHUB_TOKEN}', + 'X-GitHub-Api-Version': '2022-11-28' + } + query_params = { + 'owner': yml['owner'], + 'repo': yml['name'], + 'ref': yml['branch'], + 'path': '/environment-files/' + } + + # Get all files in the /environment-files/ folder + response = requests.get(url, headers=headers, params=query_params) + envs = response.json() + + # If the file matches the regex to be a QIIME 2 environment-file then keep + # track of its download URL + for env in envs: + if re.search(ENV_FILE_REGEX, env['name']) is not None: + env_urls.append(env['download_url']) + + +if __name__ == "__main__": + GITHUB_TOKEN = sys.argv[1] + files = sys.argv[2:] + + for file in files: + head, tail = os.path.split(file) + file_name, file_ext = os.path.splitext(tail) + + # We only care about files added to the plugins dir + if head == DIR: + with open(file, 'r') as fh: + yml = yaml.safe_load(fh) + lint(yml) + + with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: + fh.write(f'ENV_FILES={env_urls}\n') diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml new file mode 100644 index 0000000..437e669 --- /dev/null +++ b/.github/workflows/lint-pr.yml @@ -0,0 +1,84 @@ +name: lint-pr + +# Run on PR changing files in plugins dir against main +on: + pull_request: + branches: + - 'main' + paths: + - '/plugins/**' + +jobs: + lint-yml: + runs-on: ubuntu-latest + outputs: + ENV_FILES: ${{ steps.lint.outputs.ENV_FILES }} + + steps: + # Checkout new commit and prior HEAD + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + # Get diff + # This feels odd to me got it from + # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#multiline-strings + - name: Get Diff + run: | + { + echo 'DIFF<> "$GITHUB_ENV" + + # Lint all plugins/** files in diff (filtering of diff occurs in Python) + # Also gets all env files in added plugins for env testing + - name: Lint Yml and Get Env Files + id: lint + run: python .github/scripts/lint.py ${{ secrets.GITHUB_TOKEN }} $DIFF + + # Install all envs found and at least make sure `qiime info` runs + # TODO: Make this attempt to run pytest? + test-envs: + needs: lint-yml + strategy: + matrix: + os: [ubuntu-latest, macos-13] + url: ${{ fromJSON(needs.lint-yml.outputs.ENV_FILES) }} + runs-on: ${{ matrix.os }} + env: + prefix: ./test + + steps: + - name: Set up Miniconda + uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: '' + architecture: 'x64' + auto-activate-base: true + miniconda-version: 'latest' + + # Hacky stff to make it so I can activate the conda env for testing + - name: Set up Test Environment + env: + url: ${{ matrix.url }} + run: | + conda env create -y -p ${{ env.prefix }} -f $url + mkdir -p ${{ env.prefix }}/etc + cat < '${{ env.prefix }}/etc/activate.sh' + . "$CONDA/etc/profile.d/conda.sh" + conda activate '${{ env.prefix }}' + EOF + chmod +x 'test/etc/activate.sh' + + - name: Test + run: | + source ${{ env.prefix }}/etc/activate.sh + conda activate ${{ env.prefix }} + qiime info + +# Grab the target repo and validate it? + # Description? + # README? + # Env files?