Skip to content

Instantly share code, notes, and snippets.

@robdmoore
Last active August 29, 2015 14:04
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save robdmoore/32a34852cef6607850c2 to your computer and use it in GitHub Desktop.
OctopusDeploy NuGet package contents that were used to deploy iOS over-the-air ipa and build iOS and Android via PhoneGapBuild

The following files were included in a NuGet package that we used OctopusDeploy to deploy an iOS over-the-air .ipa file and also build a Cordova/PhoneGap app using the PhoneGapBuild API:

It requires the following variables to be defined in your OctopusDeploy project:

  • PhoneGapBuildAppId
  • PhoneGapBuildApiKey
  • PhoneGapBuildIosOverTheAirKey
  • PhoneGapBuildIosOverTheAirKeyPassword
  • PhoneGapBuildIosKey
  • PhoneGapBuildIosKeyPassword
  • PhoneGapBuildAndroidKey
  • PhoneGapBuildAndroidKeyPassword
  • IosOverTheAirStorageAccount

This information has been published via my blog post.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<!-- This is important. Needs to be https! -->
<string>https://{STORAGE_ACCOUNT}.blob.core.windows.net/app/app.ipa</string>
<!-- ****** -->
</dict>
<dict>
<key>kind</key>
<string>full-size-image</string>
<key>needs-shine</key>
<true/>
<key>url</key>
<!-- This is important. The non-retina sized app icon. -->
<string>https://{STORAGE_ACCOUNT}.blob.core.windows.net/app/icon.png</string>
<!-- ****** -->
</dict>
<dict>
<key>kind</key>
<string>display-image</string>
<key>needs-shine</key>
<true/>
<key>url</key>
<!-- This is important. The retina sized app icon. -->
<string>https://{STORAGE_ACCOUNT}.blob.core.windows.net/app/icon@2x.png</string>
<!-- ****** -->
</dict>
</array>
<key>metadata</key>
<dict>
<!-- This is all important -->
<key>bundle-identifier</key>
<string>{APP_NAMESPACE}</string>
<key>bundle-version</key>
<string>1.0.0</string>
<key>kind</key>
<string>software</string>
<key>subtitle</key>
<string>{APP_NAME}</string>
<key>title</key>
<string>{APP_NAME}</string>
<!-- ****** -->
</dict>
</dict>
</array>
</dict>
</plist>
$ErrorActionPreference = "Stop"
$deploypath = Split-Path $MyInvocation.MyCommand.Path
if ($OctopusDeploymentId) {
$deploypath = $OctopusParameters["OctopusOriginalPackageDirectoryPath"]
}
[Reflection.Assembly]::LoadFrom("$deploypath\Microsoft.WindowsAzure.Storage.dll") | Out-Null
[Reflection.Assembly]::LoadFrom("$deploypath\Microsoft.Data.Services.Client.dll") | Out-Null
function Create-PublicBlobContainer($storageAccount, $containerName) {
$blobClient = $storageAccount.CreateCloudBlobClient()
$container = $blobClient.GetContainerReference($containerName)
$container.CreateIfNotExists() | Out-Null
$permissions = New-Object -TypeName "Microsoft.WindowsAzure.Storage.Blob.BlobContainerPermissions"
$permissions.PublicAccess = [Microsoft.WindowsAzure.Storage.Blob.BlobContainerPublicAccessType]::Blob
$container.SetPermissions($permissions)
return $container
}
function Upload-Blob($container, $file) {
$blob = $container.GetBlockBlobReference("$($file.BaseName)$($file.Extension)")
$blob.UploadFromFile($file.FullName, [System.IO.FileMode]::Open)
if ($file.Extension -eq ".html") {
$blob.Properties.ContentType = "text/html"
}
if ($file.Extension -eq ".png") {
$blob.Properties.ContentType = "image/png"
}
if ($file.Extension -eq ".ipa") {
$blob.Properties.ContentType = "application/x-itunes-ipa"
}
if ($file.Extension -eq ".plist") {
$blob.Properties.ContentType = "binary/octet-stream"
}
$blob.SetProperties()
}
$appID = "{PGB_APP_ID_LOCAL_TESTING}"
$apiKey = "{PGB_API_KEY_LOCAL_TESTING}"
$zipFile = "app.zip"
$iosOverTheAirKey = "{PGB_IOS_OVER_THE_AIR_KEY_NAME_LOCAL_TESTING}"
$iosOverTheAirKeyPassword = "{PGB_IOS_OVER_THE_AIR_KEY_PASSWORD_LOCAL_TESTING}"
$iosKey = "{PGB_IOS_PRODUCTION_KEY_NAME_LOCAL_TESTING}"
$iosKeyPassword = "{PGB_IOS_PRODUCTION_KEY_PASSWORD_LOCAL_TESTING}"
$androidKey = "{PGB_ANDROID_PRODUCTION_KEY_NAME_LOCAL_TESTING}"
$androidKeyPassword = "{PGB_ANDROID_PRODUCTION_KEY_PASSWORD_LOCAL_TESTING}"
$version = 1,0,0,0
$storageAccount = [Microsoft.WindowsAzure.Storage.CloudStorageAccount]::DevelopmentStorageAccount
$warningsAllowed = $true
if ($OctopusDeploymentId) {
$appID = $OctopusParameters["PhoneGapBuildAppId"]
$apiKey = $OctopusParameters["PhoneGapBuildApiKey"]
$zipFile = "app.zip"
$iosOverTheAirKey = $OctopusParameters["PhoneGapBuildIosOverTheAirKey"]
$iosOverTheAirKeyPassword = $OctopusParameters["PhoneGapBuildIosOverTheAirKeyPassword"]
$iosKey = $OctopusParameters["PhoneGapBuildIosKey"]
$iosKeyPassword = $OctopusParameters["PhoneGapBuildIosKeyPassword"]
$androidKey = $OctopusParameters["PhoneGapBuildAndroidKey"]
$androidKeyPassword = $OctopusParameters["PhoneGapBuildAndroidKeyPassword"]
$version = $OctopusParameters["Octopus.Release.Number"].split(".")
$storageConnectionString = $OctopusParameters["IosOverTheAirStorageAccount"]
$storageAccount = [Microsoft.WindowsAzure.Storage.CloudStorageAccount]::Parse($storageConnectionString)
$warningsAllowed = $false
}
try
{
Write-Output "Deploying to PhoneGapBuild"
if (Test-Path .\node\node.exe) {
.\node\node node\pgb.js --appId $appID --apiKey $apiKey --zipFile $zipFile --iosOverTheAirKey $iosOverTheAirKey --iosOverTheAirKeyPassword $iosOverTheAirKeyPassword --iosKey $iosKey --iosKeyPassword $iosKeyPassword --androidKey $androidKey --androidKeyPassword $androidKeyPassword
if ($LastExitCode -ne 0) {
throw "Non-zero exit code from pgb.js"
}
} elseif ($warningsAllowed) {
Write-Warning "node not found; can't deploy to PGB"
} else {
throw "node not found; can't deploy to PGB"
}
Write-Output "Stage the .ipa file"
if (Test-Path .\build.ipa) {
mv .\build.ipa .\overtheair\app.ipa -Force
} elseif ($warningsAllowed) {
Write-Warning "build.ipa not found"
} else {
throw "build.ipa not found"
}
Write-Output "Uploading files to blob storage"
$container = Create-PublicBlobContainer $storageAccount "app"
(Get-Content $deploypath\overtheair\app.plist) -Replace "1.0.0","$($version[0]).$($version[1]).$($version[2])" | Set-Content $deploypath\overtheair\app.plist
ls -File $deploypath\overtheair | Foreach-Object {
Upload-Blob $container $_
Write-Output "Uploaded $_"
}
}
catch
{
$Host.UI.WriteErrorLine($_)
exit 1
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width" />
<title>{APP_NAME} App - Beta Testing Installation</title>
<style type="text/css">
body {
font-size: 76%;
font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
text-align: center;
padding: 20px;
}
p {
padding: 20px;
}
</style>
</head>
<body style="text-align: center;">
<h1>{APP_NAME} App</h1>
<h2>Beta testing download</h2>
<p style="text-align: justify;">If you have registered your device UDID with us then you should be able to use the below link to download the current Beta version of the app. Come back here regularly to get the latest version! If you have any problems or any feedback please let us know.</p>
<p><a href="itms-services://?action=download-manifest&url=https://{STORAGE_ACCOUNT}.blob.core.windows.net/app/app.plist"><img src="icon@2x.png" alt="[App Logo]" width="57" /><br/>Install the app</a></p>
<h2>First time here?</h2>
<p><a href="Beta.mobileprovision">Download the Beta provisioning profile</a></p>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment