将 .NET 部署到 Heroku - 构建无法创建 xproj.metaproj 项目文件

Deploying .NET to Heroku - build fails to create xproj.metaproj project file

heroku 网站上的主页链接到一个不存在的 github 页面,因此我无法使用它。 https://elements.heroku.com/buttons/herokumx/herokumxnet https://github.com/herokumx/herokumxnet

我确实找到了很多链接到此构建包和示例应用程序的 SO 帖子。 https://github.com/jincod/dotnetcore-buildpack https://github.com/jincod/AspNet5DemoApp

我尝试部署上述应用程序的完全未修改版本(您可以自己重复),但构建过程失败,没有特定错误。这是部署日志。

它抱怨找不到 xproj.metaproj,据我所知,这是一个动态创建的元项目。通常用于构建服务器。所以我假设构建过程在某个时候失败了,但我不知道在哪里或如何失败。有什么我可以添加到构建包中以获得更具体的构建错误吗?

我尝试了几次新的 clones/using 他们的内置模板系统,但是我总是出现相同的构建错误。

这是一个错误吗?还是我做错了什么?

...
remote: APT packages Installled 
remote: Installing dotnet 
remote: 
remote: Welcome to .NET Core! 
remote: --------------------- 
remote: Learn more about .NET Core @ https://aka.ms/dotnet-docs. Use dotnet
--he lp to see available commands or go to https://aka.ms/dotnet-cli-docs. 
remote: 
remote: Telemetry 
remote:-------------- 
remote: The .NET Core tools collect usage data in order to improve your experien ce. The data is anonymous and does not include commandline arguments. The data i s collected by Microsoft and shared with the community. remote: You can opt out of telemetry by setting a DOTNET_CLI_TELEMETRY_OPTOUT en vironment variable to 1 using your favorite shell. remote: You can read more about .NET Core tools telemetry @ https://aka.ms/dotne t-cli-telemetry. 
remote: 
remote: Configuring... 
remote: ------------------- 
remote: A command is running to initially populate your local package cache, to improve restore speed and enable offline access. This command will take up to a minute to complete and will only happen once. remote: Decompressing 100% 2659 ms 
remote: Expanding 100% 8029 ms 
remote: /tmp/build_bb0646bd8303182f6bd73ce264103dff/dotnet/sdk/1.0.0-preview5-00 4232/NuGet.targets(164,5): 
error MSB3202: The project file "/tmp/build_bb0646bd8 303182f6bd73ce264103dff/src/AspNet5DemoApp/AspNet5DemoApp.xproj.metaproj" was not found. [/tmp/build_bb0646bd8303182f6bd73ce264103dff/AspNet5DemoApp.sln] 
remote:  !     Push rejected, failed to compile ASP.NET Core app. 
remote: 
remote:  !     Push failed 
remote: Verifying deploy... 
remote: 
remote: !       Push rejected to ****. 
remote:

Warning: Your console font probably doesn't support Unicode. If you experience strange characters in the output, consider switching to a TrueType font such as Consolas! To https://git.heroku.com/****.git  ! 
[remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to 'https://git.heroku.com/****.git'

编辑:我也试过这个构建包,同样没有错误失败 http://github.com/heroku/dotnet-buildpack.git

remote: installing https://github.com/friism/mono-builder/releases/download/v4.0
.1.44/mono-4.0.1.44.tar.gz
remote:  !     Push rejected, failed to compile ASP.NET 5 app.

edit2:尝试使用相同的项目文件等在 windows 上复制构建脚本,并且都可以正常编译。

dotnet publish project.json --output pathtoproject\heroku-output\ --configuration Release
Publishing AspNet5DemoApp for .NETCoreApp,Version=v1.0
Project AspNet5DemoApp (.NETCoreApp,Version=v1.0) will be compiled because expected outputs are missing
Compiling AspNet5DemoApp for .NETCoreApp,Version=v1.0

Compilation succeeded.
    0 Warning(s)
    0 Error(s)

Time elapsed 00:00:02.4511992

publish: Published to ...\heroku-output\
Published 1/1 projects successfully

Edit3:我编辑了构建包以添加 - - 详细但输出没有变化。是否需要将输出提供给某种流,以便我可以读取任何可能的错误?

I used noliar's buildpack to successfully get a minimal .net core application up and running.

Steps:

1: Find the folder that you house your git repos in.

2: RightClick-->Git Bash Here on that folder.

3: Heroku create my-app-name --buildpack https://github.com/noliar/dotnet-buildpack.git

4: The response should give you the git url, clone it:

$ git clone https://git.heroku.com/my-app-name.git

5: Copy and Paste project.json and Program.cs into root of my-app-name folder. Contents of project.json:

{
    "version": "1.0.0-*"
    ,
    "buildOptions": 
    {
        "debugType": "portable"
        ,
        "emitEntryPoint": true
    }
    ,
    "dependencies": {}
    ,
    "frameworks": 
    {
        "netcoreapp1.0": 
        {
            "dependencies": 
            {
                "Microsoft.NETCore.App": 
                {
                  "type": "platform",
                  "version": "1.0.0"
                }
                ,
                "Microsoft.AspNetCore.Server.Kestrel":"1.0.0"
            }
            ,
            "imports": "dnxcore50"
        }
    }
}

Contents Of Program.cs: Based on minimal asp.net core app tutorial here: http://ardalis.com/the-minimal-aspnet-core-app With additions to get the app to bind the the correct port.

//using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

////////////////////////////////////////////////////////////////
//https://msdn.microsoft.com/en-us/library/system.environmentvariabletarget(v=vs.110).aspx
// This example demonstrates the 
//     Environment.GetEnvironmentVariable,
//     Environment.SetEnvironmentVariable, and 
//     Environment.GetEnvironmentVariables overloaded methods.
using System;
using System.Collections;
using Microsoft.Win32;
////////////////////////////////////////////////////////////////

using System.Linq;  //<--to get string[].First extention 

namespace ConsoleApplication
{
    ///<summary>
    ///This class stores the url that the heroku app will launch on.
    ///It also stores a debug message variable that we can print out
    ///to the application.
    ///</summary>
    public class UrlData
    {
        /// <summary> The url in format such as "http://localhost:5000" 
        /// that the application will attach to. </summary>
        public string url = null;

        /// <summary> A debug message that will give us some insight into what happened 
        /// in the function that produced the .url component of the UrlData. </summary>
        public string debug_message = "[DEBUG_MSG_NOT_SET]";
    }

    public class Program
    {

        public static UrlData 
        GetUrl(string[] args)
        {
             //inn=="arguments inputs by priority"
            string[] inn = new string[3]; //3 elements.

            //inn[0] = "[NOTHING_FOUND]";
            inn[0] = String.Join(" | ", args);

            //NOTE: Using "$PORT" and "PORT" both will cause crash on heroku:
            inn[1] = Environment.GetEnvironmentVariable("$PORT"); //with "$"
            //inn[2] = Environment.GetEnvironmentVariable("PORT"); //NO "$"


            //Get first non-null and non-empty entry in array:
            String dyna_port = null;
            if(true == String.IsNullOrEmpty( inn[0] )){
                //Simple processing:
                dyna_port = inn.FirstOrDefault( s => !string.IsNullOrEmpty(s) );
            }else{
                //Parse the command line args:
                //Which will look like:
                // --server.urls | 5001 | 5002 | 5003
                string[] port_args = inn[0].Split('|');
                string port_arg_name = port_args[0];
                dyna_port = port_args[1];
            }


            String port_num = (String.IsNullOrEmpty( dyna_port )) ?
                              "4998" : dyna_port;

            String use_url = "[NOT_SET_USE_URL]";
            if(port_num.Contains("http") ){
                //The command-line likely injected an argument like:
                //"http://5000:80" for the port to use.
                use_url = port_num;
            }else{
                //The command-line likely injected an argument like:
                //"5000" for the server.urls.
                //Interpret it as "Port #5000"
                use_url = "http://localhost:" + port_num;
            }

            //res_msg == "response message"
            String nl = "\n";
            String res_msg = "[Working From Port#]:" + port_num + nl +
                             "|inn[0]=="             + inn[0]   + nl +
                             "|inn[1]=="             + inn[1]   + nl +
                             "|inn[2]=="             + inn[2]   ;

            UrlData results = new UrlData();
            results.url = use_url;
            results.debug_message = res_msg;

            return results;
        }

        public static void Main(string[] args)
        {
            //Step#1: Get Url to operate on:
            UrlData ud = GetUrl( args ); //ud=="url + debug-message"

            //Uncondensed Version, so you can see what classes are being
            //Used where in the chaining:
            Microsoft.AspNetCore.Hosting.WebHostBuilder  w1;
            Microsoft.AspNetCore.Hosting.IWebHostBuilder w2;
            Microsoft.AspNetCore.Hosting.IWebHostBuilder w2_5; //2_5 == 2.5
            Microsoft.AspNetCore.Hosting.IWebHostBuilder w3;
            Microsoft.AspNetCore.Hosting.IWebHost        w4;  

            w1 = new WebHostBuilder();
            w2 = w1.UseKestrel();
            w2_5 = w2.UseUrls( ud.url );

            w3 = w2_5.Configure(
                a => a.Run(c => c.Response.WriteAsync(ud.debug_message))
            );

            w4 = w3.Build();
            w4.Run();

            Console.WriteLine("[HELLO_WORLD]");
        }
    }
}

Note: A lot of this code is very messy and experimental. But it will build. And having something to work with is always nice.

Step 6:

On git bash:

$ git add .

$ git commit

$ dotnet restore

$> dotnet run

NOTE: If you don't have the .NET CLI installed for your command line, you will need it. It's vital to make sure your applications are properly compiling before you try and push them up. It simplifies troubleshooting.

Step 7: The app should now be running on localhost:4998, if you did not configure a PORT environment variable on your local machine.

Step 8: If it runs, go ahead and do a git push and the project should be successfully deployed. More tips: 1. Heroku logs - helped me figure out what was going wrong.

  1. Read the buildpack source code and look for where $PORT is referenced.

  2. Looks like .net application cannot access the $PORT environment variable when running on heroku, so the port needs to be injected via a command line argument. Which the noliar buildpack is setup to do.

  3. This guy's post helped me understand some of the build script I was using. Especially the line:

dotnet run --server.urls http://+:8080  

Article here:

https://blog.jenyay.com/running-asp-net-core-in-heroku/

Hopefully this helped. It took me a lot of research to figure this out. Was actually hoping that I would be able to come back to your post to find it answered by someone else.

Also, sorry about the indentation on the C# code. I had to blast it all away to get the submission through.