{"id":8218,"date":"2022-05-31T11:26:45","date_gmt":"2022-05-31T10:26:45","guid":{"rendered":"https:\/\/www.blopig.com\/blog\/?p=8218"},"modified":"2022-06-02T15:57:54","modified_gmt":"2022-06-02T14:57:54","slug":"github-actions-can-be-useful","status":"publish","type":"post","link":"https:\/\/www.blopig.com\/blog\/2022\/05\/github-actions-can-be-useful\/","title":{"rendered":"GitHub actions can be useful"},"content":{"rendered":"\n<p>GitHub actions is a (relatively) novel GitHub feature that allows you to run code on GitHub when a predefined event is triggered. The most widespread use case for GitHub actions is for <a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuous_integration#Run_tests_in_CI\">Continuous Integration<\/a>, because it allows you to automatically test your code on any machine immediately after each push. For a great tutorial on how to use it for this see <a href=\"https:\/\/docs.github.com\/en\/actions\/examples\/using-scripts-to-test-your-code-on-a-runner\">here<\/a>. <\/p>\n\n\n\n<p>But you can do so much more with them!! Basically you can set up any workflow to run after any event. An event is basically when a specific activity on GitHub happens, while a workflow is basically the script you want to run after the event has happened. For a full list of the events you can use see <a href=\"https:\/\/docs.github.com\/en\/actions\/using-workflows\/events-that-trigger-workflows\">here<\/a>. Workflow scripts are written in a <em>.yml<\/em> file and should be saved within the <em>.github\/worflows<\/em> directory within your repository. I am incapable of writing a better tutorial for these than what is already on their <a href=\"https:\/\/docs.github.com\/en\/actions\/using-workflows\/about-workflows\">documentation<\/a>, but I will show a copy of a workflow script I recently put together and walk you through it.<\/p>\n\n\n\n<p>In one of my previous blog posts I wrote about how to <a href=\"https:\/\/www.blopig.com\/blog\/2021\/07\/making-your-python-tool-as-easy-to-install-as-possible\/\">upload your code to PyPI.<\/a> Hopefully I convinced you that this is quite easy, but it does require a few steps that you may not want to be doing every time you come up with a new feature (find a bug) and have to re-upload it. Luckily, you don&#8217;t have to!! Just stick the code into a GitHub actions workflow so it will automatically re-upload it for you. Here is the script I use for this:<\/p>\n\n\n\n<!--more-->\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">name: Upload Python Package\n\non:\n  release:\n    types: [created]\n\njobs:\n  deploy:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions\/checkout@v2\n    - name: Set up Python\n      uses: actions\/setup-python@v2\n      with:\n        python-version: '3.x'\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install setuptools wheel twine\n    - name: Build and publish\n      env:\n        TWINE_USERNAME: __token__\n        TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}\n      run: |\n        python setup.py sdist bdist_wheel\n        twine upload dist\/*<\/pre>\n\n\n\n<p>I think these are relatively easy to read, but I will go through some parts in more detail. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">on:\n  release:<\/pre>\n\n\n\n<p>This means I am only running this script when there is a new release. I don&#8217;t want it to upload it to PyPI every time I push some changes but only when I release a new version. If you want to run the code after a different event here is what you would change in the script.<\/p>\n\n\n\n<p>The  <code>python-version: '3.x'<\/code> line just lets GitHub actions know to use the latest python release.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">      env:\n        TWINE_USERNAME: __token__\n        TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}<\/pre>\n\n\n\n<p>If you are uploading to PyPI you will need to provide some form of authentication. This can be done by creating a token and storing it as a GitHub secret. For more information on GitHub secrets see <a href=\"https:\/\/docs.github.com\/en\/actions\/security-guides\/encrypted-secrets\">here.<\/a> <\/p>\n\n\n\n<p>And that is pretty much it!! If you got this far, I hope this was not a complete waste of your time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>GitHub actions is a (relatively) novel GitHub feature that allows you to run code on GitHub when a predefined event is triggered. The most widespread use case for GitHub actions is for Continuous Integration, because it allows you to automatically test your code on any machine immediately after each push. For a great tutorial on [&hellip;]<\/p>\n","protected":false},"author":71,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","wikipediapreview_detectlinks":true,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"ngg_post_thumbnail":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[29],"tags":[605,196,606,608,607,152],"ppma_author":[552],"class_list":["post-8218","post","type-post","status-publish","format-standard","hentry","category-code","tag-continuous-integration","tag-github","tag-github-actions","tag-github-secrets","tag-pypi","tag-python"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"authors":[{"term_id":552,"user_id":71,"is_guest":0,"slug":"brennan","display_name":"Brennan Abanades Kenyon","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/5c85dcbb5b1499e82ecfc264ec387c8302ac238c786e68cc5c92e9c21904d260?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/8218","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/users\/71"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/comments?post=8218"}],"version-history":[{"count":2,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/8218\/revisions"}],"predecessor-version":[{"id":8242,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/8218\/revisions\/8242"}],"wp:attachment":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/media?parent=8218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/categories?post=8218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/tags?post=8218"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=8218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}