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

Build PhET and PhET-iO brands together #567

Closed
samreid opened this issue Apr 20, 2017 · 55 comments
Closed

Build PhET and PhET-iO brands together #567

samreid opened this issue Apr 20, 2017 · 55 comments

Comments

@samreid
Copy link
Member

samreid commented Apr 20, 2017

In #560 we decided we want to investigate building both brands simultaneously.

@jonathanolson and @zepumph and @samreid will work together to investigate how to make this happen.

Questions:

  • how to make the build process not run too slowly? (RJS build takes about 15 seconds for me on FAMB). May be possible to reuse build artifacts, but that may be too complex.
  • Will we still have 2 dependcies.jsons? Yes, one per subdirectory.
  • what will the directory structure be like? @pixelzoom likes the idea of one subdirectory per brand.
  • can we use build directory structure for publishing? This may impact analytics and publishing steps.
  • should we turn phet-io into a flag (can be combined with brands) instead of an either-or brand? Or specifying brand='phet-io' is one way to turn on this flag?
  • making sure the build still works properly for 3rd party developers that don't have the phet-io directory checked out.
  • This will impact testing. Instead of putting "/build" in the path, you would have to put "/build/phet" in the path.

We'll try to look into this before May 4.

@samreid
Copy link
Member Author

samreid commented Apr 21, 2017

I have a faint recollection that someone within the last 2 weeks was trying to run 2 requirejs builds and we needed to clear it out somehow? Maybe it was @zepumph? I'm asking because it could impact how we can use requirejs during chipper steps.

@pixelzoom
Copy link
Contributor

It was not me.

@samreid
Copy link
Member Author

samreid commented Apr 21, 2017

@kathy-phet
Copy link

Not with the current licensing and contract statements - these say that the sims at the phet.colorado.edu website are CC-BY. It was the easiest way to be clear about which sims were available under our CC-BY license.

So if you want to do this, we will need to revisit. Why do you want to do this approach -- since its not at phet-io? It seems like it would be confusing to clients, and could cause some regular users to run the phet-io sims out of compliance with the license.

@pixelzoom
Copy link
Contributor

pixelzoom commented Apr 21, 2017

Builds on spot could presumably live side-by-side in the same directory, e.g.:

dev/html/states-of-matter/1.0.2/
  states-of-matter_en.html
  states-of-matter_en-phetio.html
  ...

But "grunt deploy-production" should deploy them to different production servers, as @kathy-phet indicated in #567 (comment).

@pixelzoom
Copy link
Contributor

pixelzoom commented Apr 21, 2017

Or if we put brands in subdirectories on spot, as discussed in yesterday's dev meet:

dev/html/states-of-matter/1.0.2/
  phet/
    states-of-matter_en.html
    ...
  phet-io/
    states-of-matter_en-phetio.html
    wrappers/
    ...

@samreid
Copy link
Member Author

samreid commented Apr 21, 2017

So if you want to do this, we will need to revisit. Why do you want to do this approach

We are looking at ways to unify the phet and phet-io development/build/test/deployment process. One recommendation from yesterdays development meeting was that the build process should build both brands during each build.

I'm mainly trying to enumerate constraints and see what's possible.

@samreid
Copy link
Member Author

samreid commented Apr 21, 2017

Brainstorming: Perhaps we can publish phet-io and phet simulations on spot and phet-io.colorado.edu. If the only restriction is not having the io simulations accessible from phet.colorado.edu, perhaps they could be blacklisted with an apache directive. Then the same build/deploy process can be used for all 3 sites.

@samreid
Copy link
Member Author

samreid commented Apr 22, 2017

Why not
https://phet.colorado.edu/sims/html/states-of-matter/1.0.2/
https://phet-io.colorado.edu/sims/html/states-of-matter/1.0.2/

That is (aside from the html/) Plan A, which involves some additional complexity to the build and deploy process. We may eventually go with it, but first it would be good to understand alternatives.

@zepumph
Copy link
Member

zepumph commented Apr 24, 2017

@jonathanolson, @samreid and I met for a bit this morning. We didn't decide on anything concrete, but rather just pursued different ideas and brainstormed pros and cons.

When thinking through the task of combining the phet-io and phet build processes together, a spectrum we thought about was how much to manipulate the build process (meaning the build server too).

On one side, a solution would be to just update the instructions to manually build the phet and phet-io sims one after another. This would be a simple(ish) implementation because the basic problem would be just combining release branches (1.1 with 1.1-phetio) so that when you manually build both it is always from the same shas. This is a bummer though because it is a hassle to add so many steps to the build process, especially if you don't care about one of the brands you are building.

We could also fork grunt into two sub processes (not a popular choice because there are potentially unforeseen problems in propagating errors/feedback through), one for the phet build and a fully separate one for the phet-io build.

The other side would be dig deep into the grunt build and make the default grunt command build a phet and a phet-io version, and put them into differently branded sub directories in the build/ dir.

Either way, maintaining and updating the dependencies.json file is a large part of the problem. If we have two fully separate dependency.json files, then it would not have to manipulate the grunt command as much (see deployUtil.commitAndPushDependeciesJSON for details), but that could be a slippery slope, having one dependencies.json file per brand.
The other option here would be to just have one dependencies file. This would work because phet-io dependencies is a superset of phet dependencies, so we could just always checkout shas for repos like phet-io and phet-io-website, even when building normal phet brand sims. (I think we seemed to prefer this strategy)

A few other talking points:

  • How do we want to handle this process in the context of 3rd party developers. If we make phet builds depend on the phet-io repo, then we need to figure out the best way around problems if someone doesn't have access to these private repos.
  • @samreid brought up the point of balancing the cost to manipulate the build process, versus the cost to adding annoyance/time to the build process. One argument is that if there are a few hundred builds in the next x amount of time, the "adding instructions for developers to manually do" method could add a few minutes to each of these builds in an annoying way, but it may be better than hours upon hours of tearing the build process apart. On the other side. If it turns out that this more manual step ends up needing changes and chipper and perennial anyways (which I think is inevitable), then perhaps we should try to do it right, in the most maintainable and forward thinking (least hackish) manner.

Please add your thoughts as you see fit, to this issue or below. @samreid and @jonathanolson and I are going to sleep on it, talk about this again soon, try to solidify a few concrete solutions with pros and cons, and then bring it up to developers on Thursday.

@zepumph
Copy link
Member

zepumph commented Apr 27, 2017

This wasn't ready for discussion in today's dev meeting. We should shoot to have a conversation about this before next dev meeting.

@samreid
Copy link
Member Author

samreid commented Apr 28, 2017

Here are some upcoming availabilities:

Tuesday May 2, 1pm-3pm Mountain Time
Wednesday May 3, 9am-3pm Mountain Time

@zepumph
Copy link
Member

zepumph commented May 1, 2017

Both of those work well for me. @jonathanolson what's good for you?

@jonathanolson
Copy link
Contributor

Tuesday sounds great to me.

@zepumph
Copy link
Member

zepumph commented May 1, 2017

Alright sounds good. How about 1pm tomorrow then?

@samreid
Copy link
Member Author

samreid commented May 2, 2017

1pm-1:50pm Tuesday works OK for me. I have another meeting at 2pm I'll need to prepare for.

@samreid
Copy link
Member Author

samreid commented May 3, 2017

We chatted about this yesterday and @pixelzoom joined in. It seems important to only have one maintenance branch per version which includes all the brands. That is, instead of having 1.1-phetio and 1.1, we would have only 1.1 and it would support all brands.

To decide:

  • should there be only one dependencies.json which identifies dependencies for all brands (as a union?) . This may be best because it enumerates everything the repo depends on to build all the brands. The main drawback seems to be that it would include private repo dependencies which not everyone can check out, so we may need to update our tools around that.
  • should the build process always output phet and phet-io brand, or should the instructions say to run grunt twice?
  • If we want to automate it, to what degree should we rewrite everything vs leverage our existing tools? For instance, if we always want to build both brands, but we don't want to invest in a chipper/perennial redesign, we could write a bash script that leverages the existing grunt tasks.

@pixelzoom
Copy link
Contributor

pixelzoom commented May 3, 2017

Off the top of my head....

should there be only one dependencies.json which identifies dependencies for all brands (as a union?) .

Having a dependencies file per brand feels like the way to go. Add the brand name as a file suffix, e.g. dependencies-phet-io.json (or dependencies-phetio.json, depending on what the brand name really is). Absence of a brand suffix could indicate phet brand, but it might be clearer (and simplify things) to have dependencies-phet.json.

Speaking of brand suffixes... This might also be the time to consider whether the HTML file for PhET brand should be (e.g.) beers-law-lab_en-phet.html instead of beers-law-lab_en.html. It would certainly simplify things to treat all brands uniformly.

should the build process always output phet and phet-io brand, or should the instructions say to run grunt twice?

This is the wrong question, it implies that there will only be phet and phet-io brands. If we're looking at longterm solutions, we need to stop thinking of this as "phet and phet-io". That said...

The build task already has a --brand option. Generalize that to --brands, similar to --locales. Absence of --brands is equivalent to --brands=*. We'll need a way to detect or enumerate the supported brands for each sim.

If we want to automate it, to what degree should we rewrite everything vs leverage our existing tools?

If PhET is really committed to brands in general, and PhET-iO in particular, then I don't think there's any argument that PhET needs a well-defined process and automated build tools to support those things. So in the longterm, there is no way to avoid incurring the large cost of modifying/developing tools and processes to support those things -- it's a question of when. "Making do" with existing tools may allow PhET to avoid the larger cost for awhile. But it will almost certainly increase the cost/complexity of a longterm solution (more manual work for developers in the meantime, more legacy "intermediate solutions" to support in the future, ...)

@samreid
Copy link
Member Author

samreid commented May 3, 2017

I agree with the majority of your comment above, the only part I am curious about is why to have different dependencies.json. It seems like that would provide the opportunity for SHAs to get out of sync. Having one dependencies.json would guarantee that SHAs are all in sync and there is no opportunity for error (same reason as we wanted to eliminate multiple maintenance branches).

I see two main options here:

  • One dependencies.json with the union of all brand shas, and if you try to check out shas for private repos, then it ignores them silently
  • One dependencies.json which tracks the shas, then other metadata (either in the build.json or dependencies-brand.json files) to track which repos each brand uses.

@pixelzoom
Copy link
Contributor

There are situations where the shas should be out of sync for each brand. Suppose you make a PhET-iO fix and want to publish only the phet-io brand in maintenance release 1.0.4. Run grunt --brand=phet-io and deploy the artifacts. dependences-phetio.json contains the dependencies, and they are at this point different than dependences-phet.json (because you didn't publish phet brand). Sometime later you have a general fix that requires publishing but phet and phet-io brands. The maintenance release will have version id 1.0.5. Run grunt --brand=* and deploy the artifacts. Now dependences-phet.json and dependences-phetio.json are identical.

@pixelzoom
Copy link
Contributor

pixelzoom commented May 3, 2017

This is probably also a good place to recommend that PhET consider having someone whose primary responsibility is supporting the building and deployment of PhET products. PhET's requirements in this area are more complicated (and unique) than the majority of organizations that I've consulted for in the past. And 100% of those organizations had someone whose full-time responsibility was to support building and deploying products. The introduction of brands and PhET-iO has increased the complexity of this significantly, and it's unreasonable to expect that this can be handled by developers whose primary responsibility is sim development.

@ariel-phet
Copy link
Contributor

Assigning to @zepumph to distill this issue and perhaps open a new distilled issue, or break out the key points into separate issues and close.

@zepumph
Copy link
Member

zepumph commented Nov 23, 2017

Here is my summary of this issue. In general I will create new issues for different parts of this. Bold parts are headers.

First we talked about what the build artifacts will look like in the build/ dir. This assumes that we are building both(all) every time, but I don't think that was settled at all.
A. Build each brand into a single directory, each with their own dependencies file:

dev/html/states-of-matter/1.0.2/
  phet/
    states-of-matter_en.html
    ...
  phet-io/
    states-of-matter_en-phetio.html
    wrappers/
    ...

B. same build folder like for spot/testing purposes:

dev/html/states-of-matter/1.0.2/
  states-of-matter_en.html
  states-of-matter_en-phetio.html

Then we talked about amount of work to be done to the build process
Spectrum: how much do we manipulate the build process to achieve this goal?

  • Side 1 - easy to implement, not very robust:
    Just combine phet-io/phet release branches, and still manually build/deploy the one you need based on the sim_deployment guidelines.

  • -- work on the automated build/deploy process to limit the steps in the sim_deployment guidelines, but you still build/deploy each brand separately

  • -- fork the grunt process into two separate sub-processes, one for each brand

  • Side 2 - hard to implement, perhaps fast/simple to run:
    Dig deep into the grunt build and make the default grunt command build a phet and a phet-io version. Maybe even using the same build artifacts so that it isn't just grunt; grunt --brand=phet-io, but much more efficient.

DECIDED: one maintenance branch per version

How do handle the dependencies files:

  • One for each brand:
    • then it would not have to manipulate the grunt command as much (see deployUtil.commitAndPushDependeciesJSON for details), but that could be a slippery slope, having one dependencies.json file per brand.
    • It seems like that would provide the opportunity for SHAs to get out of sync. (same reason as we wanted to eliminate multiple maintenance branches).
  • Only one single dependencies file:
    • This would work because phet-io dependencies is a superset of phet dependencies, so we could just always checkout shas for repos like phet-io and phet-io-website, even when building normal phet brand sims. (I think we seemed to prefer this strategy)
      • Two options of how to have 1 dependencies file:
        • One dependencies.json with the union of all brand shas, and if you try to check out shas for private repos, then it ignores them silently
        • One dependencies.json which tracks the shas, then other metadata (either in the build.json or dependencies-brand.json files) to track which repos each brand uses.

Build and Deploy each time?

  • Applying fixes (patches to dependencies.jsons) to both phet and phet-io brands (and then conditionally not deploying a specific brand if no change is needed) sounds better than having them diverge. (many thumbs ups for that comment). This means that we build and test all brands, but only deploy what we need.

Other questions not really answered:

  • What about third party developers? Build PhET and PhET-iO brands together #567 (comment)
  • Should the build process always output phet and phet-io brand, or should the instructions say to run grunt twice?
    • @pixelzoom thought:
      "This is the wrong question, it implies that there will only be phet and phet-io brands. If we're looking at longterm solutions, we need to stop thinking of this as "phet and phet-io". That said...
      The build task already has a --brand option. Generalize that to --brands, similar to --locales. Absence of --brands is equivalent to --brands=*. We'll need a way to detect or enumerate the supported brands for each sim."
  • Should PhET have someone whose primary responsibility is the build tools? Build PhET and PhET-iO brands together #567 (comment)
  • Will we have other brands that we need to support in the future?

@zepumph
Copy link
Member

zepumph commented Nov 23, 2017

Now I am going to summarize the summary:

I'm pretty sure these are decided, but it will still be good to discuss and make sure:

  • 1 dependencies.json file, that holds a superset of all shas needed for all brands
  • 1 maintenance release branch per version, that holds all brands with that version.
  • Build/test every brand in a release branch, but only deploy the brand you need to.
  • Should the default grunt task build all brands every-time by default: yes, or at least it should be able to build all brands with options like brands=*

Not really decided at all:

Assigning back to @ariel-phet to review and tagging for dev meeting.

@pixelzoom
Copy link
Contributor

Self assigning so that I remember to review comments on this issue that occurred since 11/17/17.

@pixelzoom
Copy link
Contributor

pixelzoom commented Nov 28, 2017

Re @zepumph summary in #567 (comment) ...

(1) The summary seems to be related to an unidentified discussion ("we talked about") that took place. It would be nice to have context.

(2) The directory structures don't match the decisions made in 11/16/17 dev meeting, which were approved by @kathy-phet. See "desired directory structure" in #560 (comment). Why are we changing the directory structures?

(3) I see:

DECIDED: one maintenance branch per version

If this means "one maintenance branch per {{MAJOR}}.{{MINOR}} pair" then agreed. If not, then please clarify, because this is not what was decided previously.

@pixelzoom pixelzoom removed their assignment Nov 28, 2017
@zepumph
Copy link
Member

zepumph commented Nov 28, 2017

(1) The summary seems to be related to an unidentified discussion ("we talked about") that took place. It would be nice to have context.

"Talked" meaning commented above, everything is a synopsis of the above issue comments.

(2) The directory structures don't match the decisions made in 11/16/17 dev meeting, which were approved by @kathy-phet. See "desired directory structure" in #560 (comment). Why are we changing the directory structures?

#560 (comment) is the final decision. The above is just noise. Look at #560 for finalized directory structure.

(3)

This means one maintenance branch per {{MAJOR}}.{{MINOR}} pair, with all brands built in that branch.

@samreid
Copy link
Member Author

samreid commented Nov 29, 2017

I don't have anything to add--it seems #567 (comment) is a good summary. I don't know what to do about 3rd parties that don't have phet-io checked out. Gracefully skipping it would be nice, but we would need to add checks that make sure it doesn't accidentally get omitted by a PhET developer build.

@jonathanolson
Copy link
Contributor

Should the default grunt task build all brands every-time by default: yes, or at least it should be able to build all brands with options like brands=*

The directory structures don't match the decisions made in 11/16/17 dev meeting, which were approved by @kathy-phet. See "desired directory structure" in #560 (comment). Why are we changing the directory structures?

From the above, if we want to be able to build all brands with one grunt command, we'd need to modify our file/directory structure. If we change it so they build in the same directory (please no), it will make the build-server really complicated (we have to ship the different brands to different locations).

Having multiple builds of different brands or options in different directories would be great for continuous testing (we have to make a literal copy of all source repos for every different build/brand tested right now, since we only have one build directory that gets overwritten), but might be more confusing for others.

So if we want to switch our full build/deploy/build-server system to a different scheme, we'd need to decide soon ideally. It will come with costs, and I'd recommend against it.

Do we update the build process to be graceful and fallback to just phet brand if there aren't phet-io specific repos checked out.

If we ever expect people to use our codebase, we should probably do this.

Should PhET have someone whose primary job is the build tools?

I've mostly rewritten or ported (to ES6/promises) most of chipper and perennial, and it's not that much code. Assuming others take on build-server and rosetta, I can probably take on maintenance for this without too much interruption.

Will we have other brands that we need to support in the future?

Don't have to decide now, we'll have support.

@jonathanolson
Copy link
Contributor

The majority of this work is done in the chipper 2.0 branch (decided on in #560 how to handle multiple brands).

Leaving this open for a few remaining questions (and getting it to work in cases where no phet-io dependencies are checked out).

@ariel-phet
Copy link
Contributor

Marking for dev meeting to see if this can be closed

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

No branches or pull requests

6 participants