{"id":607248,"date":"2023-02-12T07:49:47","date_gmt":"2023-02-12T13:49:47","guid":{"rendered":"https:\/\/news.sellorbuyhomefast.com\/index.php\/2023\/02\/12\/build-an-online-resume-with-an-auto-updating-pdf-version\/"},"modified":"2023-02-12T07:49:47","modified_gmt":"2023-02-12T13:49:47","slug":"build-an-online-resume-with-an-auto-updating-pdf-version","status":"publish","type":"post","link":"https:\/\/newsycanuse.com\/index.php\/2023\/02\/12\/build-an-online-resume-with-an-auto-updating-pdf-version\/","title":{"rendered":"Build an Online Resume with an Auto-Updating PDF Version"},"content":{"rendered":"<div>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/d595b45322e7bc1f844e14df1dee52ca\/e5166\/1200-og.jpg\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/d595b45322e7bc1f844e14df1dee52ca\/8ac56\/1200-og.webp 240w, \n\/static\/d595b45322e7bc1f844e14df1dee52ca\/d3be9\/1200-og.webp 480w,\n\/static\/d595b45322e7bc1f844e14df1dee52ca\/e46b2\/1200-og.webp 960w,\n\/static\/d595b45322e7bc1f844e14df1dee52ca\/92f8c\/1200-og.webp 1200w\"  type=\"image\/webp\"><source srcset=\"\/static\/d595b45322e7bc1f844e14df1dee52ca\/09b79\/1200-og.jpg 240w, \n\/static\/d595b45322e7bc1f844e14df1dee52ca\/7cc5e\/1200-og.jpg 480w,\n\/static\/d595b45322e7bc1f844e14df1dee52ca\/6a068\/1200-og.jpg 960w,\n\/static\/d595b45322e7bc1f844e14df1dee52ca\/e5166\/1200-og.jpg 1200w\"  type=\"image\/jpeg\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/d595b45322e7bc1f844e14df1dee52ca\/6a068\/1200-og.jpg\" alt=\"1200 og\" title=\"1200 og\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<p>Want a resume that stands out but doesn\u2019t cause too much trouble to edit? I have you covered.<\/p>\n<p>In this tutorial, you\u2019ll not only create a professional looking resume, but also learn about the basics of GitHub actions and Netlify.<\/p>\n<p>By the end of the article, you\u2019ll have a great looking resume with automated PDF versions in both Letter, and A4 format. And you can update it with a single text file and one commit to your GitHub repository.<\/p>\n<h2 id=\"what-well-use\"><a href=\"http:\/\/bas.codes\/#what-well-use\" aria-label=\"what well use permalink\"><\/a>What We\u2019ll Use<\/h2>\n<p>For this tutorial, we will use <\/p>\n<ul>\n<li><a href=\"https:\/\/gohugo.io\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Hugo<\/a> as a static site generator<\/li>\n<li><a href=\"https:\/\/pdf.co\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PDF.co<\/a> as a service that generates PDFs<\/li>\n<li><a href=\"https:\/\/www.netlify.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Netlify<\/a> to host our resume<\/li>\n<li><a href=\"https:\/\/github.com\/features\/actions\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub Actions<\/a> to do all the automation <\/li>\n<\/ul>\n<p>The Resume itself is based on the phantastic <a href=\"https:\/\/themes.3rdwavemedia.com\/bootstrap-templates\/resume\/devcard-bootstrap-5-vcard-portfolio-template-for-software-developers\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">DevCard<\/a> theme by Xiaoying Riley.<\/p>\n<h2 id=\"lets-go\"><a href=\"http:\/\/bas.codes\/#lets-go\" aria-label=\"lets go permalink\"><\/a>Let\u2019s Go!<\/h2>\n<h3 id=\"get-an-account-on-pdfco\"><a href=\"http:\/\/bas.codes\/#get-an-account-on-pdfco\" aria-label=\"get an account on pdfco permalink\"><\/a>Get An Account on PDF.co<\/h3>\n<p>Sign up for an account on <a href=\"https:\/\/pdf.co\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PDF.co<\/a> and head to the <a href=\"https:\/\/app.pdf.co\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Dashboard<\/a>.<br \/>\nThe service is not free per se, but comes with a generous offer of 600 credits. Enough for our resume project and a a few edits of our resume.<\/p>\n<p>On the dashboard, select \u201cView Your API key\u201d and save it somewhere. It should look like this:<\/p>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/16eb30c49c4931140ed0af119d9c43d4\/efa1a\/pdf-co-db.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/16eb30c49c4931140ed0af119d9c43d4\/8ac56\/pdf-co-db.webp 240w, \n\/static\/16eb30c49c4931140ed0af119d9c43d4\/d3be9\/pdf-co-db.webp 480w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/e46b2\/pdf-co-db.webp 960w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/f992d\/pdf-co-db.webp 1440w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/882b9\/pdf-co-db.webp 1920w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/37c59\/pdf-co-db.webp 2040w\"  type=\"image\/webp\"><source srcset=\"\/static\/16eb30c49c4931140ed0af119d9c43d4\/8ff5a\/pdf-co-db.png 240w, \n\/static\/16eb30c49c4931140ed0af119d9c43d4\/e85cb\/pdf-co-db.png 480w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/d9199\/pdf-co-db.png 960w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/07a9c\/pdf-co-db.png 1440w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/29114\/pdf-co-db.png 1920w,\n\/static\/16eb30c49c4931140ed0af119d9c43d4\/efa1a\/pdf-co-db.png 2040w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/16eb30c49c4931140ed0af119d9c43d4\/d9199\/pdf-co-db.png\" alt=\"pdf co db\" title=\"pdf co db\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<h3 id=\"get-an-account-on-netlify\"><a href=\"http:\/\/bas.codes\/#get-an-account-on-netlify\" aria-label=\"get an account on netlify permalink\"><\/a>Get An Account on Netlify<\/h3>\n<p>Next, you\u2019ll need an account at <a href=\"https:\/\/netlify.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Netlify<\/a>. Netlify is a hosting service for static sites and offers a good free tier.<\/p>\n<p>Usually, you would use Netlify to run the build jobs for you. In our case, we will do the builds on GitHub actions. <\/p>\n<p>To start a manually deployed site, just click on \u201cDeploy manually\u201d in the \u201cAdd new site\u201d dropdown.<\/p>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/1be7654418d43e5002dae28916965292\/748f4\/nf-dep-man.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/1be7654418d43e5002dae28916965292\/8ac56\/nf-dep-man.webp 240w, \n\/static\/1be7654418d43e5002dae28916965292\/d3be9\/nf-dep-man.webp 480w,\n\/static\/1be7654418d43e5002dae28916965292\/31099\/nf-dep-man.webp 656w\"  type=\"image\/webp\"><source srcset=\"\/static\/1be7654418d43e5002dae28916965292\/8ff5a\/nf-dep-man.png 240w, \n\/static\/1be7654418d43e5002dae28916965292\/e85cb\/nf-dep-man.png 480w,\n\/static\/1be7654418d43e5002dae28916965292\/748f4\/nf-dep-man.png 656w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/1be7654418d43e5002dae28916965292\/748f4\/nf-dep-man.png\" alt=\"nf dep man\" title=\"nf dep man\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<p>You need to upload a starter, so any folder with an empty <code>index.html<\/code> file is good to go.<\/p>\n<p>In the config section for your new site, click on \u201cSite settings\u201d and copy your \u201cSite ID\u201d:<\/p>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/d5ef8\/nf-site-id.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/8ac56\/nf-site-id.webp 240w, \n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/d3be9\/nf-site-id.webp 480w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/e46b2\/nf-site-id.webp 960w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/f992d\/nf-site-id.webp 1440w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/882b9\/nf-site-id.webp 1920w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/f20b7\/nf-site-id.webp 2462w\"  type=\"image\/webp\"><source srcset=\"\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/8ff5a\/nf-site-id.png 240w, \n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/e85cb\/nf-site-id.png 480w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/d9199\/nf-site-id.png 960w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/07a9c\/nf-site-id.png 1440w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/29114\/nf-site-id.png 1920w,\n\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/d5ef8\/nf-site-id.png 2462w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/6821d3147eceb915dc4a102ee4ce4cb3\/d9199\/nf-site-id.png\" alt=\"nf site id\" title=\"nf site id\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<p>Next, head over to your <a href=\"https:\/\/app.netlify.com\/user\/applications\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">user\u2019s settings<\/a> and create a personal access token:<\/p>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/737529cb8133ad786c0f465e8227ddc8\/4719e\/nf-token-1.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/737529cb8133ad786c0f465e8227ddc8\/8ac56\/nf-token-1.webp 240w, \n\/static\/737529cb8133ad786c0f465e8227ddc8\/d3be9\/nf-token-1.webp 480w,\n\/static\/737529cb8133ad786c0f465e8227ddc8\/e46b2\/nf-token-1.webp 960w,\n\/static\/737529cb8133ad786c0f465e8227ddc8\/f37ae\/nf-token-1.webp 1330w\"  type=\"image\/webp\"><source srcset=\"\/static\/737529cb8133ad786c0f465e8227ddc8\/8ff5a\/nf-token-1.png 240w, \n\/static\/737529cb8133ad786c0f465e8227ddc8\/e85cb\/nf-token-1.png 480w,\n\/static\/737529cb8133ad786c0f465e8227ddc8\/d9199\/nf-token-1.png 960w,\n\/static\/737529cb8133ad786c0f465e8227ddc8\/4719e\/nf-token-1.png 1330w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/737529cb8133ad786c0f465e8227ddc8\/d9199\/nf-token-1.png\" alt=\"nf token 1\" title=\"nf token 1\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><br \/>\n<span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/2eaf31f059c6beb471db2b886348a987\/f2f8c\/nf-token-2.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/2eaf31f059c6beb471db2b886348a987\/8ac56\/nf-token-2.webp 240w, \n\/static\/2eaf31f059c6beb471db2b886348a987\/d3be9\/nf-token-2.webp 480w,\n\/static\/2eaf31f059c6beb471db2b886348a987\/e46b2\/nf-token-2.webp 960w,\n\/static\/2eaf31f059c6beb471db2b886348a987\/f992d\/nf-token-2.webp 1440w,\n\/static\/2eaf31f059c6beb471db2b886348a987\/752cd\/nf-token-2.webp 1490w\"  type=\"image\/webp\"><source srcset=\"\/static\/2eaf31f059c6beb471db2b886348a987\/8ff5a\/nf-token-2.png 240w, \n\/static\/2eaf31f059c6beb471db2b886348a987\/e85cb\/nf-token-2.png 480w,\n\/static\/2eaf31f059c6beb471db2b886348a987\/d9199\/nf-token-2.png 960w,\n\/static\/2eaf31f059c6beb471db2b886348a987\/07a9c\/nf-token-2.png 1440w,\n\/static\/2eaf31f059c6beb471db2b886348a987\/f2f8c\/nf-token-2.png 1490w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/2eaf31f059c6beb471db2b886348a987\/d9199\/nf-token-2.png\" alt=\"nf token 2\" title=\"nf token 2\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<h3 id=\"fork-the-github-repository\"><a href=\"http:\/\/bas.codes\/#fork-the-github-repository\" aria-label=\"fork the github repository permalink\"><\/a>Fork the GitHub Repository<\/h3>\n<p>Had over to the <a href=\"https:\/\/github.com\/codewithbas\/resume\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub repository<\/a> and click the fork button. That should only take a few seconds.<\/p>\n<h3 id=\"configure-the-repository\"><a href=\"http:\/\/bas.codes\/#configure-the-repository\" aria-label=\"configure the repository permalink\"><\/a>Configure the Repository<\/h3>\n<p>Next, head over to the Repository settings page.<\/p>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/7ccb27b45adbaa8e978cd312d9863a16\/c8ad9\/gh-repo-settings.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/7ccb27b45adbaa8e978cd312d9863a16\/8ac56\/gh-repo-settings.webp 240w, \n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/d3be9\/gh-repo-settings.webp 480w,\n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/e46b2\/gh-repo-settings.webp 960w,\n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/f992d\/gh-repo-settings.webp 1440w,\n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/156b8\/gh-repo-settings.webp 1564w\"  type=\"image\/webp\"><source srcset=\"\/static\/7ccb27b45adbaa8e978cd312d9863a16\/8ff5a\/gh-repo-settings.png 240w, \n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/e85cb\/gh-repo-settings.png 480w,\n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/d9199\/gh-repo-settings.png 960w,\n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/07a9c\/gh-repo-settings.png 1440w,\n\/static\/7ccb27b45adbaa8e978cd312d9863a16\/c8ad9\/gh-repo-settings.png 1564w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/7ccb27b45adbaa8e978cd312d9863a16\/d9199\/gh-repo-settings.png\" alt=\"gh repo settings\" title=\"gh repo settings\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<p>Create a new repository secret called <code>NETLIFY_TOKEN<\/code> and put your Netlify personal access token in here.<\/p>\n<p>Next, create another repository secret called <code>PDFCO_KEY<\/code> and paste your PDF.co API key.<\/p>\n<p>In the \u201cVariables\u201d tab, create two repository variables:<\/p>\n<p><code>NETLIFY_SITE_ID<\/code> with the site ID from your Netlify settings, and <code>RESUME_URL<\/code> with the URL of your resume. It\u2019s okay to use Netlify\u2019s URL (something like <code>majestic-chaja-1234.netlify.app<\/code>) here for the moment. <\/p>\n<p>In your GitHub\u2019s repository settings, head over to \u201cActions\u201d > \u201cGeneral\u201d and make sure that \u201cRead and write permissions\u201d are set in the \u201cWorkflow Permissions\u201d section.<\/p>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/fe67848a92e4ad9664eadbf8efbc848c\/229ad\/gh-wf-perm.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/fe67848a92e4ad9664eadbf8efbc848c\/8ac56\/gh-wf-perm.webp 240w, \n\/static\/fe67848a92e4ad9664eadbf8efbc848c\/d3be9\/gh-wf-perm.webp 480w,\n\/static\/fe67848a92e4ad9664eadbf8efbc848c\/e46b2\/gh-wf-perm.webp 960w,\n\/static\/fe67848a92e4ad9664eadbf8efbc848c\/08aa0\/gh-wf-perm.webp 1356w\"  type=\"image\/webp\"><source srcset=\"\/static\/fe67848a92e4ad9664eadbf8efbc848c\/8ff5a\/gh-wf-perm.png 240w, \n\/static\/fe67848a92e4ad9664eadbf8efbc848c\/e85cb\/gh-wf-perm.png 480w,\n\/static\/fe67848a92e4ad9664eadbf8efbc848c\/d9199\/gh-wf-perm.png 960w,\n\/static\/fe67848a92e4ad9664eadbf8efbc848c\/229ad\/gh-wf-perm.png 1356w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/fe67848a92e4ad9664eadbf8efbc848c\/d9199\/gh-wf-perm.png\" alt=\"gh wf perm\" title=\"gh wf perm\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<h3 id=\"configure-your-resume\"><a href=\"http:\/\/bas.codes\/#configure-your-resume\" aria-label=\"configure your resume permalink\"><\/a>Configure Your Resume<\/h3>\n<p>Next, check out your forked repository and open it with your favourite IDE. The only file you need to edit is <code>confg.toml<\/code> which includes all the sections of your resume.<\/p>\n<p>Once you commit and push your changes, the magic will start: GitHub Actions will wind a machine up to build your resume using hugo, upload it to netlify, have pdf.co create the PDF versions, then upload the PDFs to Netlify as well, and finally commit the final PDFs to your repos. Let\u2019s see how that works in detail.<\/p>\n<h2 id=\"github-actions\"><a href=\"http:\/\/bas.codes\/#github-actions\" aria-label=\"github actions permalink\"><\/a>GitHub Actions<\/h2>\n<p>GitHub Actions are a free GitHub feature that automates tasks around your code. People use it, for example, to run automated tests on their code.<\/p>\n<p>These actions are defined in a special file called <code>.github\/workflows\/actions.yml<\/code> in our repository. <\/p>\n<p>The first two entries in the yaml file define the action\u2019s name and an event that triggers the action to run. In our case, we want the actions to run on every push to the repository.<\/p>\n<div data-language=\"yaml\">\n<pre><code><span>name<\/span><span>:<\/span> run main.py\n\n<span>on<\/span><span>:<\/span>\n  <span>push<\/span><span>:<\/span>\n    <span>branches<\/span><span>:<\/span>\n      <span>-<\/span> main<\/code><\/pre>\n<\/div>\n<p>The interesting part starts in the <code>jobs<\/code> section of the file. Jobs contain steps that run on virtual machine provided on demand by GitHub. These step build upon each other, so that the steps are like a script that automates something along the lines.<\/p>\n<p>The first steps in the resume repo check out the repository itself and install Hugo, and a Python environment for us:<\/p>\n<div data-language=\"yaml\">\n<pre><code>      <span>-<\/span> <span>name<\/span><span>:<\/span> checkout repo content\n        <span>uses<\/span><span>:<\/span> actions\/checkout@v3 <span># checkout the repository content to github runner<\/span>\n\n      <span>-<\/span> <span>name<\/span><span>:<\/span> setup python\n        <span>uses<\/span><span>:<\/span> actions\/setup<span>-<\/span>python@v4\n        <span>with<\/span><span>:<\/span>\n          <span>python-version<\/span><span>:<\/span> <span>'3.9'<\/span> <span># install the python version needed<\/span>\n          \n      <span>-<\/span> <span>name<\/span><span>:<\/span> install python packages\n        <span>run<\/span><span>:<\/span> <span>|<\/span><span>\n          python -m pip install --upgrade pip\n          pip install -r requirements.txt<\/span>\n\n      <span>-<\/span> <span>name<\/span><span>:<\/span> Setup hugo\n        <span>uses<\/span><span>:<\/span> peaceiris\/actions<span>-<\/span>hugo@v2\n        <span>with<\/span><span>:<\/span>\n          <span>hugo-version<\/span><span>:<\/span> <span>\"0.110.0\"<\/span>\n          <span>extended<\/span><span>:<\/span> <span>true<\/span><\/code><\/pre>\n<\/div>\n<p>With the next steps, we build the site using hugo and upload the public directory to Netlify:<\/p>\n<div data-language=\"yaml\">\n<pre><code>      <span>-<\/span> <span>name<\/span><span>:<\/span> Build Website\n        <span>run<\/span><span>:<\/span> hugo <span>-<\/span><span>-<\/span>minify\n\n      <span>-<\/span> <span>name<\/span><span>:<\/span> Deploy to Netlify\n        <span>run<\/span><span>:<\/span> netlify deploy <span>-<\/span><span>-<\/span>dir=public <span>-<\/span><span>-<\/span>message=\"Auto Deploy\" <span>-<\/span><span>-<\/span>prod\n        <span>env<\/span><span>:<\/span> \n          <span>NETLIFY_AUTH_TOKEN<\/span><span>:<\/span> $<span>{<\/span><span>{<\/span> secrets.NETLIFY_TOKEN <span>}<\/span><span>}<\/span>\n          <span>NETLIFY_SITE_ID<\/span><span>:<\/span> $<span>{<\/span><span>{<\/span> vars.NETLIFY_SITE_ID <span>}<\/span><span>}<\/span><\/code><\/pre>\n<\/div>\n<p>Here, we see why we needed the repository variables and secrets. They are used inside the job steps to authenticate where necessary.<\/p>\n<p>The next step generates the PDFs for us:<\/p>\n<div data-language=\"yaml\">\n<pre><code>      <span>-<\/span> <span>name<\/span><span>:<\/span> generate PDFs <span># run main.py<\/span>\n        <span>env<\/span><span>:<\/span>\n          <span>PDFCO_KEY<\/span><span>:<\/span> $<span>{<\/span><span>{<\/span> secrets.PDFCO_KEY <span>}<\/span><span>}<\/span>\n          <span>RESUME_URL<\/span><span>:<\/span> $<span>{<\/span><span>{<\/span> vars.RESUME_URL <span>}<\/span><span>}<\/span>\n        <span>run<\/span><span>:<\/span> <span>|<\/span><span>\n          mkdir static_pdf\n          python get_pdf.py\n          cp static_pdf\/*.pdf .\/static\/\n          cp static_pdf\/*.pdf .\/public\/<\/span><\/code><\/pre>\n<\/div>\n<p>The generation process itself is done using a simple API call to pdf.co. The code for this resides in the <code>get_pdf.py<\/code> file:<\/p>\n<div data-language=\"python\">\n<pre><code><span>import<\/span> requests\n<span>from<\/span> pathlib <span>import<\/span> Path\n<span>import<\/span> os\n<span>import<\/span> uuid\n\nuid <span>=<\/span> uuid<span>.<\/span>uuid4<span>(<\/span><span>)<\/span>\n<span>from<\/span> datetime <span>import<\/span> datetime\ncurrent_date <span>=<\/span> datetime<span>.<\/span>now<span>(<\/span><span>)<\/span>\nat <span>=<\/span> current_date<span>.<\/span>isoformat<span>(<\/span><span>)<\/span>\n\n\nAPI_KEY <span>=<\/span> os<span>.<\/span>environ<span>.<\/span>get<span>(<\/span><span>\"PDFCO_KEY\"<\/span><span>)<\/span>\nURL <span>=<\/span> os<span>.<\/span>environ<span>.<\/span>get<span>(<\/span><span>\"RESUME_URL\"<\/span><span>)<\/span>\n\n<span>def<\/span> <span>get<\/span><span>(<\/span>fmt<span>=<\/span><span>\"Letter\"<\/span><span>)<\/span><span>:<\/span>\n    config <span>=<\/span> <span>{<\/span>\n      <span>.<\/span><span>.<\/span><span>.<\/span>\n    <span>}<\/span>\n    url <span>=<\/span> <span>\"https:\/\/api.pdf.co\/v1\/pdf\/convert\/from\/url\"<\/span>\n    r <span>=<\/span> requests<span>.<\/span>post<span>(<\/span>url<span>,<\/span> json<span>=<\/span>config<span>,<\/span> headers<span>=<\/span><span>{<\/span><span>\"x-api-key\"<\/span><span>:<\/span> API_KEY<span>}<\/span><span>)<\/span>\n    result <span>=<\/span> r<span>.<\/span>json<span>(<\/span><span>)<\/span>\n    url <span>=<\/span> result<span>[<\/span><span>\"url\"<\/span><span>]<\/span>\n    r <span>=<\/span> requests<span>.<\/span>get<span>(<\/span>url<span>)<\/span>\n    <span>with<\/span> <span>open<\/span><span>(<\/span><span><span>f\"resume.<\/span><span><span>{<\/span>fmt<span>}<\/span><\/span><span>.pdf\"<\/span><\/span><span>,<\/span> <span>\"wb\"<\/span><span>)<\/span> <span>as<\/span> f<span>:<\/span>\n        f<span>.<\/span>write<span>(<\/span>r<span>.<\/span>content<span>)<\/span>\n    <span>return<\/span> Path<span>(<\/span><span><span>f\"resume.<\/span><span><span>{<\/span>fmt<span>}<\/span><\/span><span>.pdf\"<\/span><\/span><span>)<\/span>\n\n\n<span>if<\/span> __name__ <span>==<\/span> <span>\"__main__\"<\/span><span>:<\/span>\n    fmts <span>=<\/span> <span>[<\/span><span>'Letter'<\/span><span>,<\/span> <span>'A4'<\/span><span>]<\/span>\n    <span>for<\/span> fmt <span>in<\/span> fmts<span>:<\/span>\n        get<span>(<\/span>fmt<span>=<\/span>fmt<span>)<\/span><span>.<\/span>rename<span>(<\/span><span><span>f\"static_pdf\/resume.<\/span><span><span>{<\/span>fmt<span>.<\/span>lower<span>(<\/span><span>)<\/span><span>}<\/span><\/span><span>.pdf\"<\/span><\/span><span>)<\/span><\/code><\/pre>\n<\/div>\n<p>Again, we see the usage of repository secrets and variables inside the Python script. We can access particular values with <code>os.environ.get(\"...\")<\/code>. This way, we do not share sensitive information, such as API keys in our code.<\/p>\n<p>The last steps of our job upload the fresh PDF files to Netlify, and pushes the changes to our repo.<\/p>\n<div data-language=\"yaml\">\n<pre><code>      <span>-<\/span> <span>name<\/span><span>:<\/span> Deploy to Netlify\n        <span>run<\/span><span>:<\/span> netlify deploy <span>-<\/span><span>-<\/span>dir=public <span>-<\/span><span>-<\/span>message=\"Auto Deploy with PDFs\" <span>-<\/span><span>-<\/span>prod\n        <span>env<\/span><span>:<\/span> \n          <span>NETLIFY_AUTH_TOKEN<\/span><span>:<\/span> $<span>{<\/span><span>{<\/span> secrets.NETLIFY_TOKEN <span>}<\/span><span>}<\/span>\n          <span>NETLIFY_SITE_ID<\/span><span>:<\/span> $<span>{<\/span><span>{<\/span> vars.NETLIFY_SITE_ID <span>}<\/span><span>}<\/span>\n          \n      <span>-<\/span> <span>name<\/span><span>:<\/span> commit files\n        <span>run<\/span><span>:<\/span> <span>|<\/span><span>\n          git config --local user.email \"<span \n                data-original-string='X296QTGdY3LLXzXDXtTk\/w==7f48BzYJYTKT4bF0W5+RbZG2hcDkfZE7+9yLt87DFPnVuk='\n                class='apbct-email-encoder'\n                title='This contact has been encoded by Anti-Spam by CleanTalk. Click to decode. To finish the decoding make sure that JavaScript is enabled in your browser.'>ac<span class=\"apbct-blur\">****<\/span>@<span class=\"apbct-blur\">****<\/span>ub.com<\/span>\"\n          git config --local user.name \"GitHub Action\"\n          git add static\n          git diff-index --quiet HEAD || (git commit -a -m \"updated PDFs\" --allow-empty)<\/span>\n          \n      <span>-<\/span> <span>name<\/span><span>:<\/span> push changes\n        <span>uses<\/span><span>:<\/span> ad<span>-<\/span>m\/github<span>-<\/span>push<span>-<\/span>action@v0.6.0\n        <span>with<\/span><span>:<\/span>\n          <span>github_token<\/span><span>:<\/span> $<span>{<\/span><span>{<\/span> secrets.GITHUB_TOKEN <span>}<\/span><span>}<\/span>\n          <span>branch<\/span><span>:<\/span> main <\/code><\/pre>\n<\/div>\n<p>This is why the latest commit on the repo is always done by the Actions user<\/p>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/00300a7e946d060c22bb97b63dd90520\/a8979\/gh-actions-user.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/00300a7e946d060c22bb97b63dd90520\/8ac56\/gh-actions-user.webp 240w, \n\/static\/00300a7e946d060c22bb97b63dd90520\/d3be9\/gh-actions-user.webp 480w,\n\/static\/00300a7e946d060c22bb97b63dd90520\/e46b2\/gh-actions-user.webp 960w,\n\/static\/00300a7e946d060c22bb97b63dd90520\/f992d\/gh-actions-user.webp 1440w,\n\/static\/00300a7e946d060c22bb97b63dd90520\/f13a9\/gh-actions-user.webp 1828w\"  type=\"image\/webp\"><source srcset=\"\/static\/00300a7e946d060c22bb97b63dd90520\/8ff5a\/gh-actions-user.png 240w, \n\/static\/00300a7e946d060c22bb97b63dd90520\/e85cb\/gh-actions-user.png 480w,\n\/static\/00300a7e946d060c22bb97b63dd90520\/d9199\/gh-actions-user.png 960w,\n\/static\/00300a7e946d060c22bb97b63dd90520\/07a9c\/gh-actions-user.png 1440w,\n\/static\/00300a7e946d060c22bb97b63dd90520\/a8979\/gh-actions-user.png 1828w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/00300a7e946d060c22bb97b63dd90520\/d9199\/gh-actions-user.png\" alt=\"gh actions user\" title=\"gh actions user\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<p>This should give you a quick overview about GitHub actions. Even though we just hadle a simple resume here, it gives a glimpse on how modern software development is done in the cloud. <\/p>\n<h2 id=\"the-result\"><a href=\"http:\/\/bas.codes\/#the-result\" aria-label=\"the result permalink\"><\/a>The Result<\/h2>\n<p><span><br \/>\n      <a href=\"http:\/\/bas.codes\/static\/27d010b59177482030c5991d832d5966\/21e8f\/resume-result.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n    <span><\/span>\n  <picture><source srcset=\"\/static\/27d010b59177482030c5991d832d5966\/8ac56\/resume-result.webp 240w, \n\/static\/27d010b59177482030c5991d832d5966\/d3be9\/resume-result.webp 480w,\n\/static\/27d010b59177482030c5991d832d5966\/e46b2\/resume-result.webp 960w,\n\/static\/27d010b59177482030c5991d832d5966\/f992d\/resume-result.webp 1440w,\n\/static\/27d010b59177482030c5991d832d5966\/f114c\/resume-result.webp 1684w\"  type=\"image\/webp\"><source srcset=\"\/static\/27d010b59177482030c5991d832d5966\/8ff5a\/resume-result.png 240w, \n\/static\/27d010b59177482030c5991d832d5966\/e85cb\/resume-result.png 480w,\n\/static\/27d010b59177482030c5991d832d5966\/d9199\/resume-result.png 960w,\n\/static\/27d010b59177482030c5991d832d5966\/07a9c\/resume-result.png 1440w,\n\/static\/27d010b59177482030c5991d832d5966\/21e8f\/resume-result.png 1684w\"  type=\"image\/png\"><br \/>\n          <img decoding=\"async\" src=\"http:\/\/bas.codes\/static\/27d010b59177482030c5991d832d5966\/d9199\/resume-result.png\" alt=\"resume result\" title=\"resume result\" loading=\"lazy\">\n        <\/picture>\n  <\/a><br \/>\n    <\/span><\/p>\n<p>I have created my own resume with this repo here: <a href=\"https:\/\/resume.bas.work\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">resume.bas.work<\/a>.<\/p>\n<\/div>\n<p><a href=\"https:\/\/bas.codes\/posts\/github-actions-resume\/\" class=\"button purchase\" rel=\"nofollow noopener\" target=\"_blank\">Read More<\/a><br \/>\n Stephania Kazmierczak<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Want a resume that stands out but doesn\u2019t cause too much trouble to edit? I have you covered. In this tutorial, you\u2019ll not only create a professional looking resume, but also learn about the basics of GitHub actions and Netlify. By the end of the article, you\u2019ll have a great looking resume with automated PDF<\/p>\n","protected":false},"author":1,"featured_media":607249,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4503,1538,46],"tags":[],"class_list":{"0":"post-607248","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-build","8":"category-online","9":"category-technology"},"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/posts\/607248","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/comments?post=607248"}],"version-history":[{"count":0,"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/posts\/607248\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/media\/607249"}],"wp:attachment":[{"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/media?parent=607248"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/categories?post=607248"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/newsycanuse.com\/index.php\/wp-json\/wp\/v2\/tags?post=607248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}