{"id":22271,"date":"2022-04-05T14:19:23","date_gmt":"2022-04-05T21:19:23","guid":{"rendered":"https:\/\/salesforcedevops.net\/?p=22271"},"modified":"2022-04-05T14:31:38","modified_gmt":"2022-04-05T21:31:38","slug":"how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration","status":"publish","type":"post","link":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/","title":{"rendered":"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration"},"content":{"rendered":"\n<p class=\"has-drop-cap wp-block-paragraph\">Building automation into the software developer lifecycle (SDLC) is the quickest way a Salesforce devops management program will benefit you and your team. SDLC automation relieves developers from babysitting long-running processes. By scripting SDLC activities, Salesforce developers also start to implement continuous integration. This provides the foundation for additional capabilities to be added later, such as continuous testing and developer cybersecurity. In this <a href=\"https:\/\/origin.salesforcedevops.net\/index.php\/category\/how-to\/\">SalesforceDevops.net How To<\/a> post, I show you how to bypass change sets and use SFDX-CLI, OAuth-style authentication, and get started with a pre-written GitHub Action to automatically deploy an update and run unit tests.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<span class=\"wpex-responsive-media\"><iframe title=\"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration\" width=\"980\" height=\"551\" data-src=\"https:\/\/www.youtube.com\/embed\/GTwphi3UFMA?feature=oembed\"  allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" class=\"lazyload\" data-load-mode=\"1\"><\/iframe><\/span>\n<\/div><\/figure>\n\n\n\t\t\t\t<div class=\"wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-35f72f31      \"\n\t\t\t\t\tdata-scroll= \"1\"\n\t\t\t\t\tdata-offset= \"30\"\n\t\t\t\t\tstyle=\"\"\n\t\t\t\t>\n\t\t\t\t<div class=\"uagb-toc__wrap\">\n\t\t\t\t\t\t<div class=\"uagb-toc__title\">\n\t\t\t\t\t\t\tTable Of Contents\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"uagb-toc__list-wrap \">\n\t\t\t\t\t\t<ol class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#what-is-github-actions\" class=\"uagb-toc-link__trigger\">What is GitHub Actions?<\/a><li class=\"uagb-toc__list\"><a href=\"#salesforce-oauth-authentication\" class=\"uagb-toc-link__trigger\">Salesforce OAuth Authentication<\/a><li class=\"uagb-toc__list\"><a href=\"#development-environment\" class=\"uagb-toc-link__trigger\">Development Environment<\/a><li class=\"uagb-toc__list\"><a href=\"#what-happens-in-the-how-to\" class=\"uagb-toc-link__trigger\">What Happens in the How To<\/a><li class=\"uagb-toc__list\"><a href=\"#how-to-set-up-oauth-20-jwt-bearer-flow-for-github-actions\" class=\"uagb-toc-link__trigger\">How To Set Up OAuth 2.0 JWT Bearer Flow for GitHub Actions<\/a><li class=\"uagb-toc__list\"><a href=\"#how-to-use-github-actions-for-salesforce\" class=\"uagb-toc-link__trigger\">How To Use GitHub Actions for Salesforce<\/a><li class=\"uagb-toc__list\"><a href=\"#start-your-salesforce-continuous-integration-journey-today\" class=\"uagb-toc-link__trigger\">Start Your Salesforce Continuous Integration Journey Today!<\/a><li class=\"uagb-toc__list\"><a href=\"#credits\" class=\"uagb-toc-link__trigger\">Credits<\/a><\/ol>\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-github-actions\">What is GitHub Actions?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a> is the built-in scripting environment for GitHub repositories. All GitHub accounts have access to Actions, including free accounts using private repositories. Actions scripts are defined as YML files stored in a repository\u2019s <em>.github\/workflows<\/em> subdirectory. Actions are metered by how many minutes your Actions use each month. You get 500 free minutes per month.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Actions are invoked in response to a variety of repository events. When triggered, GitHub Actions run the commands sequenced in the YML. Actions loads a run-time BASH and NodeJS environment to run the commands. You actually have a choice of environments, including Windows and MacOS. But I recommend you stick with the latest Ubuntu Linux distribution for maximum devops compatibility.&nbsp; Using Linux allows you to write small scripts using BASH and NPM directly in Actions YML files. More complex scripting is done by writing JavaScript procedures that run on top of a pre-installed NodeJS server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This short overview has only touched the surface of Actions. There are many more capabilities, including invoking scripts on servers outside of GitHub, so please familiarize yourself with the <a href=\"https:\/\/github.com\/features\/actions\">documentation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Actions is GitHub\u2019s version of what I call a <em>command server<\/em>. I decided to come up with the command server nomenclature as an alternative to other common names for what GitHub Actions does, such as <em>CI\/CD engine<\/em>. I did this to help teach developers they are building a small, ephemeral server process. Being aware that a server is being built helps learners to understand how devops pipelines function. For example, we need a <em>server-to-server<\/em> authentication scheme to get GitHub Actions to talk to Salesforce.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-salesforce-oauth-authentication\">Salesforce OAuth Authentication<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It is tricky to authenticate SFDX-CLI from GitHub Actions. An <a href=\"https:\/\/en.wikipedia.org\/wiki\/OAuth\">OAuth<\/a>-style authentication flow is required. There are two ways to use OAuth to authenticate Salesforce from GitHub Actions, and neither way is easy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The easier of the two ways is to use the <em>SFDX Auth URL<\/em> string. This is where you first log onto an org using web or device authentication from the Terminal window in VS Code and then get an authentication URL. This is done by showing your OAuth token with the <code>sfdx force:org:display --verbose<\/code> command. Then, that URL string is stored in a GitHub repository secret.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I decided <em>not<\/em> to use this method for a couple of reasons. First, the SFDX Auth URL is tied to a developer\u2019s Salesforce user account with their current OAuth token. If that token expires or becomes invalid the GitHub secret must be updated. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The other reason I don\u2019t like SFDX Auth URL is that only one org may be authenticated with an SFDX Auth URL. What if I want to log onto multiple orgs in my GitHub Actions session? So, that\u2019s why I went to the trouble of setting up a special OAuth connection with a Connected App and a self-signed certificate and key.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-development-environment\">Development Environment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The development environment used for this How To relies <a href=\"https:\/\/code.visualstudio.com\/docs\/remote\/remote-overview\">VS Code Remote<\/a> to power up my workstation. This means I have a Linux server running in my local network that runs most of the VS Code processes. To use a remote server, I launch VS Code on my Windows workstation and connect to that server. Then, all the files, CLIs, and applications on the remote server are available to me in the VS Code interface.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">VS Code Remote lets me to use a Mac or PC as a personal workstation, and still use Linux as my devops working environment.  I find this to be a powerful way to load the tools and resources I need for SDLC management. For more information, check out <a href=\"https:\/\/origin.salesforcedevops.net\/index.php\/2021\/06\/18\/how-to-power-up-sfdx-cli-with-vs-code-remote-ssh-and-speed-up-salesforce-development\/\">this How To post on using VS Code remote<\/a> with SFDX-CLI.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Salesforce system setup used for this How To is an Enterprise org with developer and data-sample sandboxes. GitHub is used by pulling needed metadata into a new branch which supports branch-based development.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For this How To experience, I already have new and updated metadata organized in a branch that needs an automation upgrade. The pull request is complete, and the updated branch is ready to deploy to production. All the new and updated metadata has been specified in a <em>package.xml<\/em> file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To perform the deployment without a command server, I must manually execute an <code>sfdx force:source:deploy<\/code> command in the VS Code terminal. Wouldn\u2019t it be nice to just push the branch and get that done automatically?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-happens-in-the-how-to\">What Happens in the How To<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this How To exercise, I write a simple YML-only GitHub Action triggered automatically when a PUSH action occurs in the repository with the follow steps.<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li>Set up OAuth JWT Bearer Token authentication<ol><li>Open VS Code in remote repository<\/li><li>Use <em>openssl<\/em> to create a self-signed certificate and key<\/li><li>Use Salesforce Admin interface to set up connected app<\/li><li>Test local use of authentication flow<\/li><li>Store self-signed key in repository<\/li><\/ol><\/li><li>Write the GitHub Action<ol><li>Authenticate the current session with Salesforce<\/li><li>Retrieve the target repository<\/li><li>Deploy metadata and run unit tests on a production org<\/li><\/ol><\/li><li>Activate Action with a repository PUSH<ol><li>Use GitHub and Salesforce web interfaces to monitor the execution of the Action<\/li><\/ol><\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Please check out the <a href=\"https:\/\/youtu.be\/GTwphi3UFMA\">accompanying YouTube video<\/a>, you will find a complete step-by-step procedure designed for you to use by following along. You can also use <a href=\"https:\/\/gist.github.com\/vkeenan\/e21b16eb867abed0221a77059451ee7c\">this script used to produce the video<\/a> to follow along.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-to-set-up-oauth-2-0-jwt-bearer-flow-for-github-actions\">How To Set Up OAuth 2.0 JWT Bearer Flow for GitHub Actions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Authentication is very confusing already! And the nomenclature and acronyms associated with OAuth are the worst. My advice on how to deal with JSON Web Token (JWT) bearer flow authentication is to <a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_auth_jwt_flow.htm\">carefully follow the setup-by-step instructions provided by Salesforce<\/a>. Here is one confusing aspect of this nomenclature of which you will want to be aware. You won\u2019t see any JSON-formatted information while working with this scheme. Here is my summary of the process.<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li><a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_auth_key_and_cert.htm\">Use the Linux <code>openssl<\/code> command<\/a> to generate a self-signed private certificate and key. Enter your business information. When prompted, you may enter a fake Common Name. Put the files in the .<code>ssh\/jwt <\/code>directory in your home directory. Be sure to <em>not<\/em> back up that directory.<\/li><li><a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_auth_connected_app.htm\">Create a connected app on your Dev Hub org<\/a>. Name the new app \u201cGitHub Actions\u201d. For most enterprise users, the Dev Hub org is the production org. Create the app exactly according to the Salesforce instructions. Later, you will need the Connected App\u2019s Consumer Key. Get that by selecting the View option in the App Manager.<\/li><li>Refresh any sandboxes.<\/li><li>Test the authentication setup by running the <code>sfdx auth:jwt:grant<\/code> command on the same workstation from which you created the self-signed certificate.<\/li><li>In the repository Settings tab for the target repository click the Secrets option on the left. Create three secrets:<ol><li><code>SALESFORCE_CONSUMER_KEY<\/code> \u2013 The Consumer Key from your Connected App page<\/li><li><code>SALESFORCE_JWT_SECRET_KEY<\/code> \u2013 The contents of the key file generated in Step #1<\/li><li><code>SALESFORCE_DEVHUB_USERNAME<\/code> \u2013 The Salesforce username of a user authorized to perform the deployment<\/li><\/ol><\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-to-use-github-actions-for-salesforce\">How To Use GitHub Actions for Salesforce<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To get create the first GitHub Action for your SFDX-CLI project follow these three steps.<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li>Create a <code>.github<\/code> directory at the root level of your repository.<\/li><li>Create a <code>workflows<\/code> directory in the .<code>github<\/code> directory.<\/li><li>Create a new file named <code>push-action-deploy.yml<\/code> in the <code>workflows<\/code> directory.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Next, open <code>push-action-deploy.yml<\/code> with VS Code and paste in this complete GitHub Action definition. Save the file.<\/p>\n\n\n\n<script src=\"https:\/\/gist.github.com\/vkeenan\/a804be413512c1347990dea71626e484.js\"><\/script>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s go over the Actions YML file. On line 2, the <em>on<\/em> statement indicates this action will happen every time we perform a GIT PUSH on the repository. The <em>jobs<\/em> statement starts a list of one or more named Jobs which will be run. In this case, there is one job named SFDX-CLI-Deploy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>runs-on<\/code> statement indicates any run statements will be executed on the latest version of Ubuntu server. Finally, in a list of steps, a series of <code>run<\/code> and <code>uses<\/code> statements perform the steps in the action. If an error occurs during the execution of the steps, the Action aborts and GitHub will roll back any operations such as repository changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To activate the Action just commit the new file to the repository and push it to GitHub. To check the results of your GitHub Action invocation, visit the repository web page and check under the Actions tab.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And, that&#8217;s all folks!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-start-your-salesforce-continuous-integration-journey-today\">Start Your Salesforce Continuous Integration Journey Today!<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I hope you enjoyed this <a href=\"https:\/\/origin.salesforcedevops.net\/index.php\/category\/how-to\/\">SalesforceDevops.net How To<\/a> post and that you are inspired to try out GitHub Actions. Be sure to check the website for more tutorials. If you have any ideas on other Salesforce devops How To posts, please drop me a line at <a href=\"mailto:vern@vernonkeenan.com\">vern@vernonkeenan.com<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-credits\">Credits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Thank you to Salesforce, the bloggers, and other writers who helped inspire this post.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Check <a href=\"https:\/\/atrium.ai\/resources\/how-to-implement-salesforce-ci-cd-with-github-actions\/\">this Atrium blog post<\/a> for another GitHub Actions tutorial that uses the SFDX Auth URL rather than JWT.<\/li><li><a href=\"https:\/\/developer.salesforce.com\/docs\/atlas.en-us.sfdx_dev.meta\/sfdx_dev\/sfdx_dev_intro.htm\">Salesforce DX Developer Guide<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Building automation into the software developer lifecycle (SDLC) is the quickest way a Salesforce devops management program will benefit you and your team. SDLC automation relieves developers from babysitting long-running&hellip;<\/p>\n","protected":false},"author":1,"featured_media":22338,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","footnotes":""},"categories":[7],"tags":[566,150,606],"post_series":[],"class_list":["post-22271","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to","tag-github-actions","tag-sfdx-cli","tag-vs-code-remote","entry","has-media"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration - SalesforceDevops.net<\/title>\n<meta name=\"description\" content=\"In this post, I bypass change sets with SFDX-CLI, and learn how to use GitHub Actions to automatically deploy an update and run unit tests.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration - SalesforceDevops.net\" \/>\n<meta property=\"og:description\" content=\"In this post, I bypass change sets with SFDX-CLI, and learn how to use GitHub Actions to automatically deploy an update and run unit tests.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/\" \/>\n<meta property=\"og:site_name\" content=\"SalesforceDevops.net\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/salesforcedevopsnet\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-05T21:19:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-04-05T21:31:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Vernon Keenan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@salesforcedevop\" \/>\n<meta name=\"twitter:site\" content=\"@salesforcedevop\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Vernon Keenan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/\"},\"author\":{\"name\":\"Vernon Keenan\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#\\\/schema\\\/person\\\/f681893c994bc40406bb391546cd7ac8\"},\"headline\":\"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration\",\"datePublished\":\"2022-04-05T21:19:23+00:00\",\"dateModified\":\"2022-04-05T21:31:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/\"},\"wordCount\":1562,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/salesforcedevops.net\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/VideoCoverPage-githubactions-1.png\",\"keywords\":[\"GitHub Actions\",\"SFDX-CLI\",\"VS Code Remote\"],\"articleSection\":[\"How To\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/#respond\"]}],\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/\",\"url\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/\",\"name\":\"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration - SalesforceDevops.net\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/salesforcedevops.net\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/VideoCoverPage-githubactions-1.png\",\"datePublished\":\"2022-04-05T21:19:23+00:00\",\"dateModified\":\"2022-04-05T21:31:38+00:00\",\"description\":\"In this post, I bypass change sets with SFDX-CLI, and learn how to use GitHub Actions to automatically deploy an update and run unit tests.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/2022\\\/04\\\/05\\\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\\\/#primaryimage\",\"url\":\"https:\\\/\\\/salesforcedevops.net\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/VideoCoverPage-githubactions-1.png\",\"contentUrl\":\"https:\\\/\\\/salesforcedevops.net\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/VideoCoverPage-githubactions-1.png\",\"width\":1200,\"height\":675,\"caption\":\"How to use GitHub Actions\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#website\",\"url\":\"https:\\\/\\\/salesforcedevops.net\\\/\",\"name\":\"SalesforceDevops.net\",\"description\":\"Elevating Salesforce Devops with Insights and Innovation\",\"publisher\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/salesforcedevops.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#organization\",\"name\":\"SalesforceDevops.net\",\"url\":\"https:\\\/\\\/salesforcedevops.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/salesforcedevops.net\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/7760e9c16fc75961659174739887197e-sticker.png\",\"contentUrl\":\"https:\\\/\\\/salesforcedevops.net\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/7760e9c16fc75961659174739887197e-sticker.png\",\"width\":421,\"height\":421,\"caption\":\"SalesforceDevops.net\"},\"image\":{\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/salesforcedevopsnet\",\"https:\\\/\\\/x.com\\\/salesforcedevop\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/vernonkeenan\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCOgOn9rD5gyXSOmV7-Q0n7g\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/salesforcedevops.net\\\/#\\\/schema\\\/person\\\/f681893c994bc40406bb391546cd7ac8\",\"name\":\"Vernon Keenan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f1183f1ebb5c059e052825760f95b25244abc5ef832145327f298f3697f980c7?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f1183f1ebb5c059e052825760f95b25244abc5ef832145327f298f3697f980c7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f1183f1ebb5c059e052825760f95b25244abc5ef832145327f298f3697f980c7?s=96&d=mm&r=g\",\"caption\":\"Vernon Keenan\"},\"description\":\"Vernon Keenan (LinkedIn) works as a senior information technology industry consultant based in Oakland, California. He earned his B.Sc. in Biomedical Engineering at Northwestern University where he programmed a PDP-8 with punched paper tape. In his 34-year-long career he has been a teacher, SPSS programmer, database administrator, clinical researcher, technology journalist, product marketing manager, market researcher, management consultant, and industry analyst. Most recently he is a telecom operator, cloud architect, Go devops engineer and Salesforce Developer\\\/Architect. For inquiries about Salesforce strategy briefings or solution architect work please contact Vern directly at +1-510-679-1900 or vern@vernonkeenan.com.\",\"sameAs\":[\"https:\\\/\\\/ceres-gw.tnxs.net\",\"https:\\\/\\\/linkedin.com\\\/in\\\/vernonkeenan\",\"https:\\\/\\\/x.com\\\/salesforcedevop\"],\"url\":\"https:\\\/\\\/salesforcedevops.net\\\/index.php\\\/author\\\/vern\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration - SalesforceDevops.net","description":"In this post, I bypass change sets with SFDX-CLI, and learn how to use GitHub Actions to automatically deploy an update and run unit tests.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/","og_locale":"en_US","og_type":"article","og_title":"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration - SalesforceDevops.net","og_description":"In this post, I bypass change sets with SFDX-CLI, and learn how to use GitHub Actions to automatically deploy an update and run unit tests.","og_url":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/","og_site_name":"SalesforceDevops.net","article_publisher":"https:\/\/www.facebook.com\/salesforcedevopsnet","article_published_time":"2022-04-05T21:19:23+00:00","article_modified_time":"2022-04-05T21:31:38+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png","type":"image\/png"}],"author":"Vernon Keenan","twitter_card":"summary_large_image","twitter_creator":"@salesforcedevop","twitter_site":"@salesforcedevop","twitter_misc":{"Written by":"Vernon Keenan","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/#article","isPartOf":{"@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/"},"author":{"name":"Vernon Keenan","@id":"https:\/\/salesforcedevops.net\/#\/schema\/person\/f681893c994bc40406bb391546cd7ac8"},"headline":"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration","datePublished":"2022-04-05T21:19:23+00:00","dateModified":"2022-04-05T21:31:38+00:00","mainEntityOfPage":{"@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/"},"wordCount":1562,"commentCount":0,"publisher":{"@id":"https:\/\/salesforcedevops.net\/#organization"},"image":{"@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/#primaryimage"},"thumbnailUrl":"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png","keywords":["GitHub Actions","SFDX-CLI","VS Code Remote"],"articleSection":["How To"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/#respond"]}],"copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/salesforcedevops.net\/#organization"}},{"@type":"WebPage","@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/","url":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/","name":"How To Use GitHub Actions, OAuth and SFDX-CLI for Continuous Integration - SalesforceDevops.net","isPartOf":{"@id":"https:\/\/salesforcedevops.net\/#website"},"primaryImageOfPage":{"@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/#primaryimage"},"image":{"@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/#primaryimage"},"thumbnailUrl":"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png","datePublished":"2022-04-05T21:19:23+00:00","dateModified":"2022-04-05T21:31:38+00:00","description":"In this post, I bypass change sets with SFDX-CLI, and learn how to use GitHub Actions to automatically deploy an update and run unit tests.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/salesforcedevops.net\/index.php\/2022\/04\/05\/how-to-use-github-actions-oauth-and-sfdx-cli-for-continuous-integration\/#primaryimage","url":"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png","contentUrl":"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png","width":1200,"height":675,"caption":"How to use GitHub Actions"},{"@type":"WebSite","@id":"https:\/\/salesforcedevops.net\/#website","url":"https:\/\/salesforcedevops.net\/","name":"SalesforceDevops.net","description":"Elevating Salesforce Devops with Insights and Innovation","publisher":{"@id":"https:\/\/salesforcedevops.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/salesforcedevops.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/salesforcedevops.net\/#organization","name":"SalesforceDevops.net","url":"https:\/\/salesforcedevops.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/salesforcedevops.net\/#\/schema\/logo\/image\/","url":"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2021\/03\/7760e9c16fc75961659174739887197e-sticker.png","contentUrl":"https:\/\/salesforcedevops.net\/wp-content\/uploads\/2021\/03\/7760e9c16fc75961659174739887197e-sticker.png","width":421,"height":421,"caption":"SalesforceDevops.net"},"image":{"@id":"https:\/\/salesforcedevops.net\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/salesforcedevopsnet","https:\/\/x.com\/salesforcedevop","https:\/\/www.linkedin.com\/in\/vernonkeenan","https:\/\/www.youtube.com\/channel\/UCOgOn9rD5gyXSOmV7-Q0n7g"]},{"@type":"Person","@id":"https:\/\/salesforcedevops.net\/#\/schema\/person\/f681893c994bc40406bb391546cd7ac8","name":"Vernon Keenan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f1183f1ebb5c059e052825760f95b25244abc5ef832145327f298f3697f980c7?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f1183f1ebb5c059e052825760f95b25244abc5ef832145327f298f3697f980c7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f1183f1ebb5c059e052825760f95b25244abc5ef832145327f298f3697f980c7?s=96&d=mm&r=g","caption":"Vernon Keenan"},"description":"Vernon Keenan (LinkedIn) works as a senior information technology industry consultant based in Oakland, California. He earned his B.Sc. in Biomedical Engineering at Northwestern University where he programmed a PDP-8 with punched paper tape. In his 34-year-long career he has been a teacher, SPSS programmer, database administrator, clinical researcher, technology journalist, product marketing manager, market researcher, management consultant, and industry analyst. Most recently he is a telecom operator, cloud architect, Go devops engineer and Salesforce Developer\/Architect. For inquiries about Salesforce strategy briefings or solution architect work please contact Vern directly at +1-510-679-1900 or vern@vernonkeenan.com.","sameAs":["https:\/\/ceres-gw.tnxs.net","https:\/\/linkedin.com\/in\/vernonkeenan","https:\/\/x.com\/salesforcedevop"],"url":"https:\/\/salesforcedevops.net\/index.php\/author\/vern\/"}]}},"uagb_featured_image_src":{"full":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",1200,675,false],"thumbnail":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1-150x150.png",150,150,true],"medium":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1-300x169.png",300,169,true],"medium_large":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1-768x432.png",768,432,true],"large":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1-1024x576.png",980,551,true],"1536x1536":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1-1536x864.png",1536,864,true],"2048x2048":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",1200,675,false],"lightbox":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",1200,675,false],"search_results":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1-125x125.png",125,125,true],"blog_entry":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",750,422,false],"blog_post":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",750,422,false],"blog_post_full":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",1200,675,false],"blog_related":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",1200,675,false],"gallery":["https:\/\/salesforcedevops.net\/wp-content\/uploads\/2022\/04\/VideoCoverPage-githubactions-1.png",1200,675,false]},"uagb_author_info":{"display_name":"Vernon Keenan","author_link":"https:\/\/salesforcedevops.net\/index.php\/author\/vern\/"},"uagb_comment_info":3,"uagb_excerpt":"Building automation into the software developer lifecycle (SDLC) is the quickest way a Salesforce devops management program will benefit you and your team. SDLC automation relieves developers from babysitting long-running&hellip;","_links":{"self":[{"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/posts\/22271","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/comments?post=22271"}],"version-history":[{"count":0,"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/posts\/22271\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/media\/22338"}],"wp:attachment":[{"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/media?parent=22271"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/categories?post=22271"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/tags?post=22271"},{"taxonomy":"post_series","embeddable":true,"href":"https:\/\/salesforcedevops.net\/index.php\/wp-json\/wp\/v2\/post_series?post=22271"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}