Skip to content
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

Return version in hosting:channel:deploy #3157

Merged
merged 14 commits into from May 19, 2021

Conversation

slam
Copy link
Contributor

@slam slam commented Feb 22, 2021

Description

firebase hosting:clone accepts two forms of the source argument - site:channel and site@version. The second form allows cloning a specific version and is great for many companies that have a robust QA process to validate a preview build before promoting it to live.

However, there is currently no way to extract the version that was deployed. This PR adds the version info to the hosting:channel:deploy output.

Scenarios Tested

Run firebase hosting:channel:deploy <test-channel> with and without the --json option. Make sure the version info appears in both text and json outputs.

Sample Commands

Example output:

Text:

✔  hosting:channel: Channel URL (<site-name>): https://<site-name>--<channel>-bf71pekc.web.app [expires 2021-02-28 16:26:30] [version 5b47f66ce57331b4]

JSON:

{
  "status": "success",
  "result": {
    "<site-name>": {
      "site": "<site-name>",
      "url": "https://<site-name>--<channel>-bf71pekc.web.app",
      "version": "a44e17f03a7e3c2c",
      "expireTime": "2021-03-01T00:25:13.973338740Z"
    }
  }
}

@google-cla google-cla bot added the cla: yes Manual indication that this has passed CLA. label Feb 22, 2021
Copy link
Contributor

@bkendall bkendall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea here, but I'm not certain that this is safe as-is because it changes the returned value of deploy. If you check the output of deploy --json before and after, it must not be a breaking change (well, it can be, but that would require a different effort).

Comment on lines 37 to 39
[site: string]: {
[key: string]: string;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might the value of this map be the Release interface in hosting/api.ts? (I don't know off hand, but it would make for stronger typing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great idea. It would require a bit more code changes to capture the payload returned by the hosting release api, but it makes more sense to me. Let me give it a try.

Comment on lines 145 to 147
const results = (await deploy(["hosting"], options, {
hostingChannel: channelId,
})) as DeployResult;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My TS-brain is rusty: could this be const results: DeployResult = await deploy() rather than using as?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method deploy() returns any since it is implemented in js. Without the as cast, eslint issues this warning: Unsafe assignment of an any value..

I'm fine with either construct. Please advise.

Comment on lines 155 to 157
if (siteDetails && siteKey in siteDetails) {
d.version = siteDetails[siteKey]["version"];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the case where siteDetails is not defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Removed.

@@ -107,8 +107,12 @@ var deploy = function (targetNames, options, customContext = {}) {
_.each(context.hosting.deploys, function (deploy) {
logger.info(clc.bold("Hosting URL:"), utils.addSubdomain(api.hostingOrigin, deploy.site));
});
const versionNames = context.hosting.deploys.map((deploy) => deploy.version);
return { hosting: versionNames.length === 1 ? versionNames[0] : versionNames };
var siteDetails = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var siteDetails = {};
const siteDetails = {};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had const initially, but then noticed that this js file is using var everywhere else. I'd like to leave it as var if it is okay with you.

return { hosting: versionNames.length === 1 ? versionNames[0] : versionNames };
var siteDetails = {};
context.hosting.deploys.forEach((deploy) => {
var version = deploy.version.replace(`sites/${deploy.site}/versions/`, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not actually sure we want to truncate the full name to just the version ID. If we wanted to only display that later, we can manipulate the name at that location.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. Will move that logic into host-channel-deploy.ts.

var version = deploy.version.replace(`sites/${deploy.site}/versions/`, "");
siteDetails[deploy.site] = { version };
});
return { hosting: siteDetails };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change may also have an effect on the output of deploy --json. Could you check the before/after of the behavior there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks compatible. The only new field is version.

Before:

{
  "status": "success",
  "result": {
    "<site>": {
      "site": "<site>",
      "url": "https://<site>--slam-test-6161efgc.web.app",
      "expireTime": "2021-03-02T19:40:07.615661137Z"
    }
  }
}

After:

{
  "status": "success",
  "result": {
    "<site>": {
      "site": "<site>",
      "url": "https://<site>--slam-test-6161efgc.web.app",
      "version": "09ef5462c91e2bba",
      "expireTime": "2021-03-02T19:39:05.793378023Z"
    }
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense to me because before this PR the return value of deploy() was not used anywhere:

https://github.com/firebase/firebase-tools/pull/3157/files#diff-90fa65dc2e075506e4e87cc1c6bee0c8a1e769440908e956179ad0fa4a79d999L130

@slam slam requested a review from bkendall February 23, 2021 23:56
@slam
Copy link
Contributor Author

slam commented Mar 9, 2021

@bkendall could you pls review again when you get a chance?

@slam
Copy link
Contributor Author

slam commented Mar 27, 2021

@bkendall could you pls review again when you get a chance?

It's been a month since I responded to the feedback. Is there anything else I could do to speed this up?

@bkendall
Copy link
Contributor

Thanks for your patience. Unfortunately there's been other more pressing things on my plate recently, but I hope to come back around to this soon.

@bkendall
Copy link
Contributor

When I do a normal deploy (firebase deploy --only hosting) on master, I get this output (with --json):

{
  "status": "success",
  "result": {
    "hosting": "sites/bkend-test-stuff/versions/db18ce3e1f438cb2"
  }
}

Now I'm getting an object at that hosting key rather than a string (which is a breaking change):

{
  "status": "success",
  "result": {
    "hosting": {
      "bkend-test-stuff": {
        "release": {
          "name": "sites/bkend-test-stuff/releases/1617216425557023",
          "version": {
            "name": "sites/bkend-test-stuff/versions/e23837c2b1183abb",
            // Other fields trimmed for sanity
        }
      }
    }
  }
}

Checking on hosting:channel:deploy, it does look like only version is added, which is safe.

Looking at the code, I think the version may be able to be pulled from the bit of code that gets/creates the channels before calling deploy. That would allow the version to be added into hosting:channel:deploy's output while not changing firebase deploy's output. What do you think?

Copy link
Contributor

@bkendall bkendall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(See previous comment regarding firebase deploy)

@slam slam requested a review from bkendall April 3, 2021 04:59
@slam
Copy link
Contributor Author

slam commented Apr 3, 2021

(See previous comment regarding firebase deploy)

Thank you for the explanation and the example. I finally got it.

Updated the code. Decided not to touch src/deploy/index.js at all, and limited all the changes to hosting:channel:deploy.

Copy link
Contributor

@bkendall bkendall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. Could you add an entry to the changelog?

- Adds the deployed version to the output when deploying to Firebase Hosting.

LGTM otherwise! Thanks for being incredibly patient with me

@slam slam requested a review from bkendall May 13, 2021 18:56
@@ -137,9 +160,18 @@ export default new Command("hosting:channel:deploy [channelId]")
if (d.expireTime) {
expires = `[expires ${bold(datetimeString(new Date(d.expireTime)))}]`;
}
const versionPrefix = `sites/${d.target || d.site}/versions/`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this out with a test project that has two sites and deploy targets set up for them. This line ends up breaking because d.target isn't what d.site is (target is the local alias for it). I think .site is the only thing that's needed here.

Suggested change
const versionPrefix = `sites/${d.target || d.site}/versions/`;
const versionPrefix = `sites/${d.site}/versions/`;

Could you double check this fix? I think it should be fine, but it'd be nice for you to test as well :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. version is empty:

$ firebase --debug hosting:channel:deploy t1-test --project slam-home-api --json --only t1   
{
  "status": "success",
  "result": {
    "t1": {
      "site": "thing1",
      "target": "t1",
      "url": "https://thing1--t1-test-ltf4oe3y.web.app",
      "version": "",
      "expireTime": "2021-05-21T00:12:33.800426131Z"
    }
  }
}

Will fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed:

$ firebase --debug hosting:channel:deploy t1-test --project slam-home-api --json --only t1
{
  "status": "success",
  "result": {
    "t1": {
      "site": "thing1",
      "target": "t1",
      "url": "https://thing1--t1-test-ltf4oe3y.web.app",
      "version": "9af1bb9abd9d5d01",
      "expireTime": "2021-05-21T00:16:09.860986599Z"
    }
  }
}

@slam slam requested a review from bkendall May 14, 2021 00:17
Copy link
Contributor

@bkendall bkendall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I may not merge it right this moment, but I'll do so soon! Thanks for the PR!

@bkendall bkendall merged commit 6862f4c into firebase:master May 19, 2021
@slam slam deleted the slam/hosting-deploy-version-info branch May 19, 2021 23:17
devpeerapong pushed a commit to devpeerapong/firebase-tools that referenced this pull request Dec 14, 2021
* Return version  in `hosting:channel:deploy`

* Improve text loggin

* Incorporate review comments

* Add version without changing the deploy output in json

* Unroll even more changes

* Add an entry to CHANGELOG.md

* Fix a bug when target is specified

Co-authored-by: Bryan Kendall <bkend@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Manual indication that this has passed CLA.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants