Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Dec 22, 2018 @ 02:50
    Nicholas Westby
    0

    Transferring Non-Content with Umbraco Deploy?

    I am using Umbraco Formulate on Umbraco Cloud, and I'd like it to play a bit nicer with Umbraco Deploy.

    That is, I want to be able to create a form on one environment, and then transfer it to another environment with Umbraco Deploy. I can already sort of do this so long as I make all changes to forms on my local environment, because I can then commit the forms to Git (forms are stored as files).

    I'm not really sure how to go about this, but I'm thinking there are a few possible ways:

    • Value Connector Create a value connector so that when a page has a picked form is transferred, the form is transferred too (kind of like how media gets transferred if it's picked by a page). I'm not even sure if this is possible, but I could see this working.
    • Transfer Dialog I could create a dialog that, when you right click, allows a user to select "Transfer", and that will then transfer the form to the specified environment. This would treat forms more like data.
    • Commit to Git If there were some way to let Umbraco Cloud know about a newly created file, I could hopefully have Umbraco Cloud commit forms to the repo whenever they're created/modified/deleted. This would be treating forms similarly to how document types are treated (the difference being that the form on the file system isn't really a remnant, but it's the entity itself).

    I have no idea how to go about any of this. Is there documentation to go through? Maybe a repo that shows one of these approaches working? Perhaps you have some knowledge of which approach is most viable?

    Anything you can do to help to get me started would be appreciated.

    I do note that there is this repo: https://github.com/umbraco/Umbraco.Deploy.Contrib

    Trouble is, it seems to only be for property editors. Formulate has its own section and doesn't really store much in the database (aside from the form picker property editor). I doubt it would show how to transfer files that don't exist in the database.

  • Søren Kottal 702 posts 4497 karma points MVP 5x c-trib
    Dec 22, 2018 @ 19:26
    Søren Kottal
    1

    Hi Nicholas

    There was a talk on this topic at Codegarden 16. You can see the video here: https://vimeo.com/channels/codegarden16/183620667

    I would love to have the ability to notify Deploy about a newly created file, in order to get it committed. I have an issue here https://issues.umbraco.org/issue/UAAS-649

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Dec 22, 2018 @ 21:06
    Nicholas Westby
    0

    Hi Søren,

    First off, thanks for that video. It might be enough to get me started, but I'll have to start digging in some code to see if I can make it work for my scenario.

    Also, I've moved your issue over to GitHub since Umbraco is no longer using the old issue tracker: https://github.com/umbraco/Umbraco.Cloud.Issues/issues/33

    Although the video was for Courier rather than Umbraco Deploy, I'm hoping that the concepts are essentially the same in Umbraco Deploy. From what I gather, there are two things I need to do:

    • Subclass ItemProvider I apparently need to subclass ItemProvider to make Umbraco Cloud aware of how to deal with my type of item (e.g., to serialize/deserialize).
    • Notification I need to send a notification to Umbraco Cloud using BasicEventManager.SendToCache so Umbraco Cloud knows that my item needs to be transferred.

    Seems like this means I would transfer the form files over HTTP rather than via Git. It's unclear to me if this creates an item in the queue or if it just transfers instantly, but my guess is it tosses it in the queue. Or maybe it does toss it in Git (like it does with the file artifact that corresponds to a document type).

    I will tinker with it a bit to see if I can figure something out, but I would still love if somebody with some experience in this area could point me in the right direction.

    For example, since I'm dealing with files, maybe the right way to deal with it in my item provider is to add a dependency (maybe there is a built-in one for generic files) rather than serializing the already serialized form. It's still not super clear to me at this point.

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jan 02, 2019 @ 18:00
    Nicholas Westby
    1

    Seems like ItemProvider and BasicEventManager do not exist in Umbraco Deploy, so that's a dead end.

    I poked around the code and noticed something like this may be possible:

    var service = default(Umbraco.Deploy.ISourceControlService);
    service.AddFiles("name", "type", new[] { "file1.txt" });
    

    This brings up some questions:

    • Interface Instance How do I get an instance of the class the implements that interface?
    • Name/Type What are the name/type parameters for?
    • Files What format should the files be in (e.g., c:\website\file1.txt or /file1.txt or ~/file1.txt)?

    My hope is that I can use ISourceControlService.AddFiles to add files to Git when running on Umbraco Cloud. If somebody could provide some answers to the above questions, that would go a long way toward figuring this out.

    I suppose I might also only want to call AddFiles() when in Umbraco Cloud (i.e., not when running on a local developer's computer), so if there is some boolean I can check to see if the current environment is Umbraco Cloud (e.g., CurrentEnvironment.IsUmbracoCloud), that may also be of use. Though, I could also see it being the case that AddFiles() already takes this into account. Hard to say without seeing the source.

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jan 03, 2019 @ 01:49
    Nicholas Westby
    0

    Hmmm, no luck getting an instance of ISourceControlService so far. I tried to create a class that implements IValueConnector and that had an ISourceControlService parameter in the constructor, but I got an error message:

    Unresolved dependency [Target Type: formulate.deploy.MyTestValueConnector], [Parameter: sourceControlService(Umbraco.Deploy.ISourceControlService)], [Requested dependency: ServiceType:Umbraco.Deploy.ISourceControlService, ServiceName:]
    

    Not really sure I can get an instance of the class without using some brittle reflection shenanigans, and it may end up that this will not even work how I'm hoping.

    Any help on this would be appreciated. I'm banging my head against a wall.

  • Søren Kottal 702 posts 4497 karma points MVP 5x c-trib
    Jan 03, 2019 @ 07:22
    Søren Kottal
    0

    Hi Nicholas

    If you open Umbraco.Deploy.dll in dotPeek or similar, you can search for usages of ISourceControlService, and see how it is implemented. I did that, and it gave me an idea of what to do. I haven't tried if it works yet though.

    I'm not sure if this breaches the license, so I'm not going to add more details for now :)

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jan 03, 2019 @ 16:38
    Nicholas Westby
    0

    Hi Søren,

    I'd love to hear what you discovered. Can you send me a message here? https://code101.net/contact/

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jan 03, 2019 @ 18:33
    Nicholas Westby
    0

    I noticed I can get an instance of ISourceControlService via Umbraco.Deploy.DeployComponent.SourceControlService. I'll toy with that a bit to see if I can make anything happen.

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jan 03, 2019 @ 20:10
    Nicholas Westby
    101

    I figured it out!

    This is what you need to do:

    var service = global::Umbraco.Deploy.DeployComponent.SourceControlService;
    var path = "~/App_Data/Formulate/Json/Forms/fb06ee9c2dc84512bc13e3679e23d3e1.form";
    path = HostingEnvironment.MapPath(path);
    service.AddFiles("fb06ee9c2dc84512bc13e3679e23d3e1.form", "Form", new[] { path });
    

    The first two parameters of AddFiles are used to construct a message for the Git commit. In this case, that message would be Adding Form 'fb06ee9c2dc84512bc13e3679e23d3e1.form'.

    I imagine they are also used in the Umbraco Cloud UI, but in that UI it just said "Worked on Other and changed one item" (I imagine because it doesn't recognize "Form" as a known type, it just defaults to referring to it as "Other").

    I tried 7 variations of the file path, and the one in which I map the path using HostingEnvironment.MapPath was the only one that seemed to work (FYI, that's in the System.Web.Hosting namespace).

    One other thing to note is that you'll need the Umbraco Deploy MyGet feed in order to install the UmbracoDeploy NuGet package (e.g., if you have a class library). You can ensure you have access to that feed by adding a NuGet.config file in the same directory as your Visual Studio .sln file with the following contents:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageSources>
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
        <add key="MyGet Umbraco Deploy" value="https://www.myget.org/F/uaas/api/v3/index.json" />
      </packageSources>
    </configuration>
    

    That will ensure you have access to both the normal NuGet feed as well as the Umbraco Deploy MyGet feed.

    FYI, the AddFiles call only seems to do anything on Umbraco Cloud environments (i.e., it seemed to be unnecessary to add a check to see if a developer is running on their local).

    Really, really wish this were documented. I suppose it now is, in a way.

  • Søren Kottal 702 posts 4497 karma points MVP 5x c-trib
    Jan 04, 2019 @ 07:19
    Søren Kottal
    1

    Great that you got it working!

    I was going in another direction by reimplementing the AddFiles method, but never got to try it out. Your solution seems a lot better!

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jan 04, 2019 @ 18:38
    Nicholas Westby
    0

    Yep, it does seem like the best way to go at present, even if it is "accidental" and "undocumented": https://github.com/umbraco/Umbraco.Cloud.Issues/issues/33

    Comment from Above GitHub Link

    Since it works, this is what I'll be going with for now. If anybody discovers an alternative at some point in the future, please do reply with that information.

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jan 05, 2019 @ 00:31
    Nicholas Westby
    1

    If anybody is curious to see a working implementation, I just made one:

    Store to Umbraco Cloud

    Clicking "Store to Umbraco Cloud" calls AddFiles(): https://github.com/rhythmagency/formulate/commit/ea5228404f257350b18779157f6c10756f41eb52

    You can also see that I'm calling RemoveFiles() when "Remove from Cloud" is clicked. One thing to note about RemoveFiles is that it both removes the file from Git and the file system. That was not clear to me at first, so I'll probably have to go back and make this a bit more sophisticated.

Please Sign in or register to post replies

Write your reply to:

Draft