Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Use SHA for deploy preview urls #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Use SHA for deploy preview urls #9

wants to merge 1 commit into from

Conversation

BrunnerLivio
Copy link

Fixes #6

@BrunnerLivio BrunnerLivio marked this pull request as ready for review June 14, 2020 19:31
@JakePartusch
Copy link
Owner

@BrunnerLivio, this looks awesome! Thanks for taking this on!

Could we add an action to test this feature? Alongside the one in .github/workflows/main.yml? Otherwise, it looks good to go :)

@BrunnerLivio
Copy link
Author

BrunnerLivio commented Jun 14, 2020

@JakePartusch yes I thought about testing. Though quite hard to do so, since your website you test against is not the same as this repo, meaning it would use the wrong SHA for the deploy preview.

Edit:
Ohh I think I have not checked correctly, seems like the website is included in the repo. Let me setup another workflow to test this change :-)

@JakePartusch
Copy link
Owner

🤔 Looks like the new check failed.

It attempted to reach out to:
https://6c3d413090a8286c00c23429--happy-kilby-80bc73.netlify.app
But the actual url was this:
https://5ee696a8832e3a00089a221a--happy-kilby-80bc73.netlify.app

Do you have any idea why that might be, @BrunnerLivio ?

@BrunnerLivio
Copy link
Author

@JakePartusch currently trying to find out why. It seems like Netlify is not using the SHA as suspected :/ Netlify Docs is not helping either... I'll do some research, let's see

@BrunnerLivio
Copy link
Author

Asked the question in the Discourse of Netlify. Was not able to figure it out..

https://community.netlify.com/t/how-is-the-netlify-per-commit-deploy-preview-url-being-computed/16918

@lunelson
Copy link

There's a fork of this action, which does what this PR does 🤷 https://github.com/JosephDuffy/wait-for-netlify-action

It uses github.context.payload.head instead of github.context.payload.number for the commit hash, which I'm guessing is the issue here

@JakePartusch
Copy link
Owner

@BrunnerLivio want to give this a shot ☝️ ?

Maybe github.context.sha is different than github.context.payload.head for some reason?

Or maybe there is a setting in Netlify that needs to be adjusted? The deploy url doesn't seem to match any commit hashes. At least in my project.

@lunelson
Copy link

@JakePartusch yeah after I commented on that I ran in to the same problem. I'm going to post a question to netlify support about how to determine the deploy hash

@lunelson
Copy link

Searching for this it looks like @BrunnerLivio got an answer...soI guess it’s going to be harder than it seems but maybe there’s a way to use the Netlify API to find out what the URL will be

https://community.netlify.com/t/how-is-the-commit-deployed-url-being-put-together/16917/2

@lunelson
Copy link

I did some experimenting with this today, taking Netlify's JS API client netlify instead of axios; what's required to do this, is looking up the deploys associated with the site to find the deploy id corresponding to the commit, which first requires looking up the sites associated with a given account ("Team" in Netlify terms), to find the ID of the site corresponding to the site name. The final function should look something like this:

const core = require("@actions/core");
const github = require("@actions/github");
const Netlify = require('netlify');

const run = async () => {
  try {
    const commitRef = github.context.payload.head;
    const accessToken = core.getInput('access_token')
    const accountSlug = core.getInput('account_slug')
    const siteName = core.getInput('site_name')
    const maxTimeout = Number(core.getInput("max_timeout")) || 60;
    /* insert checks here, to fail if any of these inputs are invalid */
    const client = new Netlify(accessToken)
    const getDeployId = async () => {
      let sites, site, deploys, deploy;
      try {
        sites = await client.listSitesForAccount({account_slug: accountSlug});
        site = sites.find(site => site.name === siteName);
      } catch (e) {
        const errMsg = 'account slug or site name invalid';
        console.warn(errMsg);
        throw new Error(errMsg);
      }
      const iterations = maxTimeout / 3;
      for (let i = 0; i < iterations; i++) {
        try {
          deploys = await client.listSiteDeploys({ site_id: site.id });
          deploy = deploys.find(deploy => deploy.commit_ref === commitRef);
          return deploy.id;
        } catch (e) {
          console.warn('commit deploy not (yet) available; retrying in 3s')
          await new Promise(r => setTimeout(r, 3000));
        }
      }
      const errMsg = 'timed out: commit deploy was unavailable';
      console.warn(errMsg);
      throw new Error(errMsg);
    }
    console.log(`Waiting for the Netlify deploy`);
    const deployId = await getDeployId();
    const url = `https://${deployId}--${siteName}.netlify.app`;
    core.setOutput("url", url);
  } catch (error) {
    core.setFailed(error.message);
  }
};

run();

@JakePartusch
Copy link
Owner

Thanks @lunelson — this looks great!

I think that we'll want to continue to support the current functionality (without an API key). But I definitely think it makes sense to provide an "enhancement" to support per-commit deploys (with an access key).

We can keep this PR open for now to continue with discussion, but I think it would make sense to open a separate PR to work through the scenarios for this.

Thanks again for your work on this @BrunnerLivio and @lunelson 🎉

@lunelson
Copy link

...so here's something else: I found out about the check_run and check_suite events, which fire globally in the repo whenever checks performed by an App (like Netlify's—a check_suite) run. This means it's also possible to run things precisely after specific check suites without having to poll for the availability of the new build...but unfortunately the data returned by Netlify's check suite still doesn't contain the deploy ID so the same acrobatics with the Netlify API are required anyway

@BrunnerLivio
Copy link
Author

BrunnerLivio commented Jun 21, 2020

@lunelson that is an awesome investigation! Is it also possible to receive whenever a specific job has been finished? Otherwise, we could bypass the strategy above and just wait for the job to finish :)

Let's close this PR, but we can ofc still continue the discussion

@lunelson
Copy link

@BrunnerLivio yes if you install the following workflow on the master branch in a repo with any Github App installed (apps are what run "Check Suites"), it will fire when the check suite is finished, and all the information comes through in the github context;

on: 
  check_suite:
    types: completed
jobs:
  dump_context:
    runs-on: ubuntu-latest
    steps:
      - name: Dump GitHub context
        env:
          GITHUB_CONTEXT: ${{ toJson(github) }}
        run: echo "$GITHUB_CONTEXT"

However, it fires globally for any and all check_suite events in the repo—not in the PR—so it comes through in the repo's global list of action runs, not in the action runs for the given PR; therefore my current idea is to build on this to fire a repository_dispatch webhook event, on the PR branch, so that inside the PR a workflow could run against an event like below, and hopefully also receive the information it needs (the deploy URL) inside the client_payload—but I'd have to test this, I'm still not sure if it will come through as an event in the PR:

on:
  repository_dispatch:
    types: [netlify_checks_completed]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Does not reliably work when adding a commit to an existing deploy preview
3 participants