diff --git a/.github/ISSUE_TEMPLATE/update-external-links-gallery.md b/.github/ISSUE_TEMPLATE/update-external-links-gallery.md new file mode 100644 index 00000000..c91bfb02 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/update-external-links-gallery.md @@ -0,0 +1,35 @@ +--- +name: Update external links gallery +about: Update external links gallery +title: '' +labels: 'external-links-gallery-submission' +--- + + + +Checklist of required entries: + +- [ ] `url` is specified +- [ ] `title` is specified +- [ ] `description` is specified + +```yaml +--- +url: '' +thumbnail: '' +title: '' +description: '' +authors: + - name: '' + affiliation: '' + affiliation_url: '' + email: '' + - name: '' + affiliation: '' + affiliation_url: '' + email: '' +--- + +``` + + diff --git a/.github/workflows/collect-user-submission.py b/.github/workflows/collect-user-submission.py new file mode 100644 index 00000000..38818bbb --- /dev/null +++ b/.github/workflows/collect-user-submission.py @@ -0,0 +1,81 @@ +import json +import os +import typing + +import frontmatter +import pydantic +from markdown_it import MarkdownIt + + +class Author(pydantic.BaseModel): + name: str = 'anonymous' + affiliation: str = None + affiliation_url: typing.Union[str, pydantic.HttpUrl] = None + email: typing.Union[str, pydantic.EmailStr] = None + + +class Submission(pydantic.BaseModel): + title: str + description: str + url: pydantic.HttpUrl + thumbnail: typing.Union[str, pydantic.HttpUrl] = None + authors: typing.List[Author] = None + + +@pydantic.dataclasses.dataclass +class IssueInfo: + gh_event_path: pydantic.FilePath + submission: Submission = pydantic.Field(default=None) + + def __post_init_post_parse__(self): + with open(self.gh_event_path) as f: + self.data = json.load(f) + + def create_submission(self): + self._get_inputs() + self._create_submission_input() + return self + + def _get_inputs(self): + self.author = self.data['issue']['user']['login'] + self.title = self.data['issue']['title'] + self.body = self.data['issue']['body'] + + def _create_submission_input(self): + md = MarkdownIt() + inputs = None + for token in md.parse(self.body): + if token.tag == 'code': + inputs = frontmatter.loads(token.content).metadata + break + name = inputs.get('name') + title = inputs.get('title') + description = inputs.get('description') + url = inputs.get('url') + thumbnail = inputs.get('thumbnail') + _authors = inputs.get('authors', []) + authors = [] + if _authors: + for item in _authors: + authors.append( + Author( + name=item.get('name', 'anyonymous'), + affiliation=item.get('affiliation'), + affiliation_url=item.get('affiliation_url'), + email=item.get('email', ''), + ) + ) + else: + authors = [Author(name='anyonymous')] + + self.submission = Submission( + name=name, title=title, description=description, url=url, thumbnail=thumbnail, authors=authors + ) + + +if __name__ == '__main__': + + issue = IssueInfo(gh_event_path=os.environ['GITHUB_EVENT_PATH']).create_submission() + inputs = issue.submission.dict() + with open('gallery-submission-input.json', 'w') as f: + json.dump(inputs, f) diff --git a/.github/workflows/update-external-links-gallery.yaml b/.github/workflows/update-external-links-gallery.yaml new file mode 100644 index 00000000..e1c5c695 --- /dev/null +++ b/.github/workflows/update-external-links-gallery.yaml @@ -0,0 +1,151 @@ +name: Update External Links Gallery + +on: + issues: + types: + - opened + - edited +jobs: + validate-user-submission: + if: | + github.repository == 'ProjectPythia/projectpythia.github.io' + && contains(github.event.issue.labels.*.name, 'external-links-gallery-submission') + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - name: Find Comment + uses: peter-evans/find-comment@v1 + id: fc + with: + issue-number: ${{ github.event.issue.number }} + comment-author: 'github-actions[bot]' + body-includes: Thank you for your contribution + - name: Create comment + if: steps.fc.outputs.comment-id == '' + uses: peter-evans/create-or-update-comment@v1 + with: + issue-number: ${{ github.event.issue.number }} + body: | + Thank you for your contribution 🎉, @${{ github.actor }}! + + We're currently running [validation checks](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) to make sure the contents of your submission are okay. An update will be posted here shortly once the validation checks are passing. + - name: Update comment + if: steps.fc.outputs.comment-id != '' + uses: peter-evans/create-or-update-comment@v1 + with: + comment-id: ${{ steps.fc.outputs.comment-id }} + edit-mode: replace + body: | + Thank you for your contribution 🎉, @${{ github.actor }}! + + We're currently running [validation checks](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) to make sure the contents of your submission are okay. An update will be posted here shortly once the validation checks are passing. + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install dependencies + run: | + python -m pip install pip --upgrade + python -m pip install python-frontmatter markdown-it-py pydantic[email] + + - name: Validate input + run: | + python .github/workflows/collect-user-submission.py + exit 0 + + - uses: actions/upload-artifact@v2 + with: + name: submission + path: gallery-submission-input.json + + create-pull-request: + needs: validate-user-submission + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + - uses: actions/download-artifact@v2 + with: + name: submission + + - name: Display structure of downloaded artifacts + run: | + ls -R + + - name: Install dependencies + run: | + python -m pip install pip --upgrade + python -m pip install ruamel.yaml pre-commit + + - name: Update gallery + shell: python + run: | + import json + from ruamel.yaml import YAML + + yaml = YAML() + submission_file = 'gallery-submission-input.json' + links_file = 'content/links.yaml' + with open(submission_file) as f: + data = json.load(f) + + with open(links_file) as f: + links = yaml.load(f) + + with open(links_file, 'w') as f: + links.append(data) + yaml.dump(links, f) + + - name: Run pre-commit hooks + run: | + python -m pre_commit run --all-files + + - name: Create pull request + id: cpr + uses: peter-evans/create-pull-request@v3 + with: + commit-message: 'Update external links gallery' + committer: GitHub + author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> + signoff: false + branch: external-links-gallery-${{ github.event.issue.number }} + title: 'Update external links gallery' + body: | + Update external links gallery as requested in #${{ github.event.issue.number }}. + + - name: Find Comment + uses: peter-evans/find-comment@v1 + id: fc + with: + issue-number: ${{ github.event.issue.number }} + comment-author: 'github-actions[bot]' + body-includes: We've created a pull request on your behalf + + - name: Create comment + if: steps.fc.outputs.comment-id == '' + uses: peter-evans/create-or-update-comment@v1 + with: + issue-number: ${{ github.event.issue.number }} + body: | + @${{ github.actor }}, your submission looks great! We've created a pull request on your behalf using the information you provided. + + The pull request can be accessed from this url: ${{ steps.cpr.outputs.pull-request-url }}. + + - name: Update comment + if: steps.fc.outputs.comment-id != '' + uses: peter-evans/create-or-update-comment@v1 + with: + comment-id: ${{ steps.fc.outputs.comment-id }} + edit-mode: replace + body: | + @${{ github.actor }}, your submission looks great! We've created a pull request on your behalf using the information you provided. + + The pull request can be accessed from this url: ${{ steps.cpr.outputs.pull-request-url }}. diff --git a/setup.cfg b/setup.cfg index 59778fa1..7d88de0b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,7 +7,7 @@ select = B,C,E,F,W,T4,B9 [isort] known_first_party= -known_third_party=matplotlib,pandas,yaml +known_third_party=frontmatter,markdown_it,matplotlib,pandas,pydantic,yaml multi_line_output=3 include_trailing_comma=True force_grid_wrap=0