如何设置TeamCity CI以便解压缩Xamarin组件?

时间:2014-01-11 22:22:40

标签: teamcity xamarin mvvmcross

enter image description here

在Visual Studio中,一切正常,并且使用适当的dll创建了一个Components目录。但是,TeamCity无法检索Android支持库dll,因为还原的触发器是在加载解决方案时运行的Xamarin VS插件。 Xamarin的nuget包恢复等效于xamarin-component。我已将xamarin-component.exe放在我的C:\ Windows目录中。为了配置TeamCity,我在

之前添加了一个命令行构建步骤
Command executable: xamarin-component 
Command parameters: restore mysolution.sln

TeamCity作为NT Authority \ System运行。所以使用PsExec,

psexec -i -s %SystemRoot%\system32\cmd.exe

如果我然后运行'xamarin-component login'

INFO (login): Computed cookie jar path: C:\Windows\system32\config\systemprofile\.xamarin-credentials 
INFO (login): Computed cookie jar path: C:\Windows\system32\config\systemprofile\.xamarin-credentials 
INFO (login): Credentials successfully stored.

当我在cmd中找到我的解决方案并尝试恢复时,我试图下载组件,然后是Json解析错误。这与我在TeamCity中遇到的错误相同。

teamcity

如果我使用'Administrator'(将凭据存储在C:\ Users \ Administrator中,我收到错误。早些时候,当我使用我的个人帐户时,它确实有效。但是,一旦我删除了C:\ Users \蒂姆\ AppData \ Local \ Xamarin \ Cache \ Components,出现了同样的问题.Fiddler表明,不是让Json回来(就像我们输入无效令牌时那样),我们得到一个302重定向,表示对象已移动 。这是xamarin 登录页面 - 显然不是Json。

试过。  1.将COOKIE_JAR_PATH设置为C:\ Users \ tim.xamarin-credentials - xpkg拾取但同样的错误  2.将.xamarin-credentials从Config \ system32复制到D:\,将COOKIE_JAR_PATH设置为D:.xamarin-credentials- xpkg拾取但错误相同  3.将.xamarin-credentials移动到C:\,设置COOKIE_JAR_PATH - 相同的错误  4.使用COOKIE_JAR_PATH重新登录NT Authority到C:.xamarin-credentials - 相同的错误

我现在的临时想法是找出NT Authority xamarin组件在哪里查找Cache并将文件放在那里。

C:\Windows\system32\config\systemprofile\AppData\Local\Xamarin\Cache\Components\xamandroidsupportv4-18-4.18.1.xam

我的xamarin组件的版本是0.99 - 对于100,我们更努力......

4 个答案:

答案 0 :(得分:3)

我实际上没有让cookie jar从system32路径正确加载 。我认为这是一个路径虚拟化问题,我只是不能很好地理解它的正面或反面。

我最后添加了一个工具将从中读取的环境变量(我是Xamarin的主要作者:-),它指定了要读取的cookie jar路径,这解决了其他使用TeamCity的问题。环境变量为COOKIE_JAR_PATH

您可以将它从TeamCity的环境设置中设置为指向system32配置文件目录之外的cookie jar路径(我认为在我原来的测试中,我把它放在C:驱动器的根目录中,但它可以在任何地方,真)。

答案 1 :(得分:3)

作为一个黑客,我从

复制了Cache文件夹
C:\Users\tim\AppData\Local\Xamarin 

C:\Windows\system32\config\systemprofile\AppData\Local\Xamarin\

绕过了与Xamarin服务器的通信。

更新。我怀疑它可能是服务器端的错误链接或设置。调用xamarin-component restore时,会调用

GET /api/available_versions?alias=xamandroidsupportv4-18 HTTP/1.1

返回“对象移到这里”,其中“这里”无处可去。

oh noes

如果在删除Cache and Components文件夹(解决方案旁边)后启动Visual Studio,Xamarin会调用

GET /api/download/xamandroidsupportv4-18/4.18.1 HTTP/1.0

有一个类似的外观对象移动到,但这一次它引导你到xamarin-components.s3.amazonaws.com /

oh yes

GET /fdca922d2b77799fe208a08c9f3444fe/xamandroidsupportv4-18-4.18.1.xam HTTP/1.0

可能是某些内容已更改,或者available_versions API已更改。

答案 2 :(得分:2)

非常感谢您提出这个问题及其答案。我真的不喜欢在构建节点上存储auth cookie或者必须手动复制缓存的想法,所以我想出了我自己的解决方案,所以我用一个模拟行为的快速Powershell脚本来解决这个问题。 xamarin-component.exe restore操作:

param
(
    [Parameter(Mandatory=$true)]
    $authCookie,

    [Parameter(Mandatory=$true)]
    $componentDirectory,

    [Parameter(Mandatory=$true)]
    $project
)

[void]([System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem'))
$xml = [xml] $(cat $project);
$components = $xml.Project.ItemGroup.XamarinComponentReference | ? { $_.Include.Length -gt 0 } | % { $_.Include };

if (!(test-path $componentDirectory))
{
    echo "$componentDirectory didn't exist, so it was created.";
    [void](mkdir $componentDirectory);
}

foreach ($component in $components)
{
    $source = "http://components.xamarin.com/download/$component";
    $destination = "$componentDirectory\$component.zip";

    if (test-path $destination)
    {
        echo "$destination already exists, skipping...";
        continue;
    }

    echo "Downloading $component from $source to $destination...";

    $client = New-Object System.Net.WebClient
    $client.Headers.Add([System.Net.HttpRequestHeader]::Cookie, "XAM_AUTH=$authCookie");

    try
    {
        $client.DownloadFile($source, $destination);
    }
    catch
    {
        # The error message will be on one of these lines hopefully:
        write-error "Failed to download! Errors are below:";
        write-error $_
        write-error $_.Exception
        write-error $_.Exception.InnerException
        write-error $_.Exception.InnerException.InnerException
        exit 1;
    }

    if (!(test-path $destination))
    {
        write-error "$destination doesn't exist - the download must have failed!";
        exit 1;
    }

    echo "Decompressing $source to $componentDirectory"
    [System.IO.Compression.ZipFile]::ExtractToDirectory($destination, $componentDirectory)
    echo ""
}

echo "Done!";

可以从浏览器中的XAM_AUTH cookie或主目录中的.xamarin-credentials“cookiejar”中提取-authCookie参数。让它像这样参数化是很好的,这样你就可以将它作为一个秘密变量存储在TeamCity中。

componentDirectory参数必须是组件目录的完整路径 - 如果它不存在,它将被创建。

project参数应该是您要为其恢复包的项目的路径 - 如果您有多个需要此项目的项目,则必须为每个项目执行脚本。不要指定您的解决方案,因为它不起作用。

不幸的是,这对于Xamarin的突发奇想并不是很有弹性 - 简单的API更改可能会使这无用,所以显然最好的解决方案是等待Xamarin解决这个问题。我通过电子邮件发送了Xamarin的支持来抱怨这个问题,但我不认为我会得到及时的回复(这些天他们似乎非常忙)。我希望这很有用!

答案 3 :(得分:0)

创建目录并将该目录路径放在环境变量XAMARIN_CACHEPATH

enter image description here