Skip to content

Expand the build infrastructure support #867

Closed

Description

@tannergooding

The build infrastructure for ImageSharp is rather limited today and doesn't always follow best practices.

It would be ideal if this could be updated to have cross-platform build scripts, rely on things like Directory.Build.props/targets for centralizing build metadata, and generally be updated to do things like work with long paths, with paths that have spaces in the name, and where the working directory is not the repo root.

Activity

  1. tannergooding commented on Mar 29, 2019

    @tannergooding
    ContributorAuthor

    @JimBobSquarePants, I know I had discussed this with you briefly at the MVP summit; but if I were to provide some fixes here; would you prefer it incrementally or in one big PR?

  2. tannergooding commented on Mar 29, 2019

    @tannergooding
    ContributorAuthor

    Would you also prefer it in a PR or with a layout of changes discussed here first?

  3. JimBobSquarePants commented on Mar 30, 2019

    @JimBobSquarePants
    Member

    Hey @tannergooding

    Yeah this would be great! Looking forward to seeing what will change.

    I think the best bet would be a layout of changes here and everything in a big fat PR. That way we can avoid any interim complexity in the build process.

  4. added this to the 1.0.0-rc1 milestone on Mar 30, 2019
  5. tannergooding commented on Apr 22, 2019

    @tannergooding
    ContributorAuthor

    I think there a couple potential options here:

    1. Take a dependency on a "build toolchain" like dotnet/arcade. This is what Roslyn, CoreFX, and other repositories are currently using. CoreCLR and other dotnet repositories are planning on moving to it as well.
    2. You could go with a smaller more customized approach and rewrite your own infrastructure to how you need.

    The process overall would be fairly similar for both, mostly just differing in whether you have code props/targets locally or if you are directing those same props/targets to the dotnet/arcade NuGet package.

    The primary recommendations I have are:

    1. Use Directory.Build.props and Directory.Build.targets to share common project properties/targets/etc. This also makes it easy to bring down shared toolset packages or analyzers.
    2. Rewrite the build scripts to have both sh and cmd versions (the cmd version forwards to ps1). This also needs to handle common issues like paths that have a space in their name, pulling down build dependencies, or triggering the scripts from any folder (not just the repo root). It should also provide a consistent interface across all platforms/architectures (so you can easily move between Linux, Windows, OSX, etc).

    I've been going with the second option (customized approach) in my own projects as I find it easier to understand/reason about and find it I can't be caught in surprise by changes that arcade makes for dotnet which might not be applicable to me. The drawback, is I'm responsible for my own infrastructure and bringing functionality on-board as needed.

    You can see an example of my current infrastructure here: https://github.com/terrafx/terrafx. It isprimarily centered around easy "inner loop" scripts in the repo root that forward to the real build scripts in the scripts folder. There is then the root Directory.Build.props/targets which defines core properties like language version, packing options, NuGet restore sources, and the Roslyn Compiler Toolset to depend on. The sources and tests folders then have their own Directory.Build.props/targets (which import the root ones) and define things specific to them. These include the testing dependencies, InternalsVisibleTo support, and build output subdirectories (which I find make it easier to locate things in my artifacts folder).

  6. JimBobSquarePants commented on Apr 23, 2019

    @JimBobSquarePants
    Member

    Lots of great ideas and info here, thanks!

    I'm undecided.... I appreciate the risks involved in taking on Arcade but I also believe that any breaking changes will most likely have well documented resolution.

  7. tannergooding commented on Apr 25, 2019

    @tannergooding
    ContributorAuthor

    Let me know when you have made a decision and I'm happy to get the PR up for whichever you prefer.

  8. JimBobSquarePants commented on Apr 25, 2019

    @JimBobSquarePants
    Member

    Let’s go with Arcade, that way we can copy MS when something changes. Thanks, really appreciate this! 😄

  9. antonfirsov commented on Apr 25, 2019

    @antonfirsov
    Member

    Does the underlying CI infrastructure matter, when considering the options? Currently we are stuck with AppVeyor+Travis, but we are planning to migrate to Azure Pipelines in the future.

  10. tannergooding commented on Apr 25, 2019

    @tannergooding
    ContributorAuthor

    Does the underlying CI infrastructure matter, when considering the options? Currently we are stuck with AppVeyor+Travis, but we are planning to migrate to Azure Pipelines in the future.

    It shouldn't. The majority of it is controlled via centralized build scripts that CI is configured to call.

  11. antonfirsov commented on Apr 25, 2019

    @antonfirsov
    Member

    Arcade sounds fine to me.

  12. tannergooding commented on Apr 30, 2019

    @tannergooding
    ContributorAuthor

    Ok, so I had been working on getting the arcade support working but the arcade team has indicated that it is only intended for Microsoft owned repos. This is partially because it has some explicit support for some internal tooling (like MicroBuild) but also because it is believed that most of the core functionality (such as localization, versioning, source linking, etc) should be part of the .NET SDK instead and bugs should be logged against .NET SDK, MSBuild, and NuGet when that functionality is missing.

    I'm still happy to help rev the infrastructure, but unfortunately, it looks like dotnet/arcade is not going to be a viable (or at least not supported) path forward.

  13. JimBobSquarePants commented on Apr 30, 2019

    @JimBobSquarePants
    Member

    Thanks for investigating; we can live with that, plan B it is! 😄

  14. 2 remaining items

  15. tannergooding commented on May 1, 2019

    @tannergooding
    ContributorAuthor

    Then I can include the support for it as part of these infrastructure changes. We just need to determine who generates the original SNK file and then have it checked in (unmodified) so that it can be consumed and enabled by the infrastructure PR.

  16. antonfirsov commented on May 1, 2019

    @antonfirsov
    Member

    @tannergooding that would be great!

    @JimBobSquarePants will correct me if I am wrong, but I don't think we have any preference or expectation regarding SNK generation. As far as I am aware, you are free to do it on your branch, if you want.

  17. JimBobSquarePants commented on May 2, 2019

    @JimBobSquarePants
    Member

    @antonfirsov @tannergooding Am I correct in saying we care about is that whoever generates the public key just needs to send us the private key partner? (I know next to nothing about SNK generation).

    If I'm right just generate one as part of this PR and send us the requisite parts.

  18. tannergooding commented on May 2, 2019

    @tannergooding
    ContributorAuthor

    @JimBobSquarePants, it's a bit simpler than that even. Someone just needs to create the key and check it into source control: https://docs.microsoft.com/en-ca/dotnet/standard/library-guidance/strong-naming.

    ✔️ CONSIDER adding the strong naming key to your source control system.

    A publicly available key lets developers modify and recompile your library source code with the same key.

    You shouldn't make the strong naming key public if it has been used in the past to give special permissions in partial-trust scenarios. Otherwise, you might compromise existing environments.

    This is fine since SNKs aren't used for security and it just allows users to produce the same deterministic bits. You'll notice that other repos, such as Roslyn, have their public/private key combination checked in as well.

  19. tannergooding commented on May 18, 2019

    @tannergooding
    ContributorAuthor

    Got some more work done on this, changes are still in https://github.com/tannergooding/ImageSharp/tree/infrastructure.

    It now builds successfully and I believe the remaining work is:

    • Fix up the yml scripts for CI
      • Actually, I haven't done the build script work yet, so that might not be needed and it might be mergeable after resolving the below. The build scripts could then be handled as a separate step.
    • Ensure that various things like CodeCoverage and other misc test options work
    • Validate that all tests pass for all configurations/etc
    • Finish figuring out how signing should work
      • Some of the external SixLabors dependencies need to be signed first, which means you may want the key in as part of "standard"
  20. tannergooding commented on May 18, 2019

    @tannergooding
    ContributorAuthor

    The interesting bits are likely:

    • Fleshed out the .editorconfig to have the current settings + all code style defaults that weren't specified
      • This should make it easier to see what the defaults are and to customize where things don't match up with what you want
      • The one difference from the defaults is csharp_indent_case_contents_when_block, which I set to false since most people don't want the double indentation that is otherwise the default
      • The end_of_line default was changed to lf since that is what git will check it in as (all platforms) and is what git will check it out as on Unix. It makes for better cross-platform consistency.
    • Directory.Build.props files in the root and src/tests folders that defines defaults for the projects under the respective directories
    • Deleted the NuGet.config as the options can be specified in the Directory.Build.props
    • Reorganized the solution file to match the source hierarchy for solution items, as it makes it easier to find things (did not include files from submodules in this)
  21. JimBobSquarePants commented on May 25, 2019

    @JimBobSquarePants
    Member

    Apologies for the slow reply. That's all looking good.

    So how does Directory.Build.Props work with nuget then? Does it automatically update as we install or update new dependencies?

  22. tannergooding commented on May 25, 2019

    @tannergooding
    ContributorAuthor

    So how does Directory.Build.Props work with nuget then?

    Unfortunately, not very well today. The tooling in general isn't super supportive of centrally managed properties yet and most UX will still modify the project file instead of your Directory.Build.props.

    It is likely something that will get addressed eventually, especially since this is a model followed by the dotnet repos.

  23. tannergooding commented on May 27, 2019

    @tannergooding
    ContributorAuthor

    @JimBobSquarePants, I think I've got basically everything working for the Directory.Build.props/targets changes and I could put that up as an initial PR (which would also avoid needing to continually fix up things as the repo progresses).

    The only blocker looks to be figuring out how signing should work. More specifically, some of the external SixLabors dependencies need to be signed first, which means you may want the key in as part of "standard".

    For that to happen, I would need to submit a PR checking the SNK into https://github.com/SixLabors/Standards and then also update whatever produces SixLabors.Core, SixLabors.Fonts, SixLabors.Shapes, and SixLabors.Shapes.Text to build with that SNK, correct?

  24. JimBobSquarePants commented on May 28, 2019

    @JimBobSquarePants
    Member

    For that to happen, I would need to submit a PR checking the SNK into https://github.com/SixLabors/Standards and then also update whatever produces SixLabors.Core, SixLabors.Fonts, SixLabors.Shapes, and SixLabors.Shapes.Text to build with that SNK, correct?

    Yeah that's correct. If we add it there it can be consumed everywhere. I'm happy to progress as soon as you are. 👍

  25. antonfirsov commented on Aug 11, 2019

    @antonfirsov
    Member

    @tannergooding I guess certain parts of the top-level Directory.Build.props shall be moved to SixLabors/Standards so we can reuse common stuff like strong naming in all our repos.
    Is this reasonable? Easy/hard to achieve?

  26. tannergooding commented on Aug 12, 2019

    @tannergooding
    ContributorAuthor

    Its reasonably easy. The only real requirement here is that you still need to have a Directory.Build.props/Directory.Build.targets in the repo root which imports the shared props/targets (which would be under the standards submodule folder).

    The same goes for other places where you want to import some shared props/targets and only have it impact the projects under that folder.

    That is, Directory.Build.props/targets are still searched and imported from the current folder up.

    So, if you wanted some shared solution-wide props/targets, some shared source only props/targets, and some shared test only props/targets; you might have a setup like the following:

    • repo-root
      • Directory.Build.props -- imports standards\{name1}.props
      • Directory.Build.targets -- imports standards\{name1}.targets
      • src
        • Directory.Build.props -- imports standards\{name2}.props, imports repo-root\Directory.Build.props
        • Directory.Build.targets -- imports standards\{name2}.targets, imports repo-root\Directory.Build.targets
      • tests
        • Directory.Build.props -- imports standards\{name3}.props, imports repo-root\Directory.Build.props
        • Directory.Build.targets -- imports standards\{name3}.targets, imports repo-root\Directory.Build.targets

    etc

  27. antonfirsov commented on Aug 12, 2019

    @antonfirsov
    Member

    Makes sense, thanks! I think this should be the next step, so we can uniformize our builds across the repository tree + enable strong naming everywhere.
    @tannergooding any chance you can help with it in the near future (1-2 months)?
    @dlemstra any chance you can touch this topic while dealing with GitHub CI?

  28. JimBobSquarePants commented on Apr 21, 2020

    @JimBobSquarePants
    Member

    I'm gonna close this. We've got strong naming and we've made many infrastructural changes to the build since this was raised. Any specific issues can be raised again in the future.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions