Can't create releases from the UI on config as code project

Hi, I’ve cloned a project and moved it to config as code. This succeeds but when I try to create a release I get an empty page (see image). On the original project I can create releases without issues. This is happening on chrome and edge browsers. My Octo version is v2022.1 b2584

The browser console displays the following error message:

feedRepository.ts:69 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'Links')
    at i.searchPackages (feedRepository.ts:69:37)
    at CreateOrEditRelease.tsx:856:62
    at Array.map (<anonymous>)
    at s (CreateOrEditRelease.tsx:854:58)
    at CreateOrEditRelease.tsx:906:33
    at Array.map (<anonymous>)
    at CreateOrEditRelease.tsx:906:22
    at re.doBusyTaskInternal (DataBaseComponent.tsx:122:20)
    at re.<computed> [as doBusyTaskInternal] (BaseComponent.tsx:135:32)
    at re.doBusyTask (DataBaseComponent.tsx:51:21)

Hi @pazrodrigo,

Thanks for getting in touch, though I’m sorry to see you’re hitting this unexpected issue! We’ve seen what I believe is this exact same issue in your version range before, which was a result of having a custom step template in your process referencing a package, showing this same error in the browser console. This bug was fixed in 2022.2.969, though I’d like to try to confirm if this is the case or not definitively.

Do you see any warnings in your version controlled project’s process? This issue also showed an error similar to Feed 'Feeds-ID' could not be found within individual steps in your process.

I look forward to hearing back and getting to the bottom of this one!

Best regards,

Kenny

@Kenneth_Bates we don’t have custom step templates on this particular project, but we do have custom script modules if that may help. We run package, service fabric and azure cli steps. I also don’t see any warnings on the process page (nor under settings/general or settings/source control)

FYI updating to build 2661 doesn’t fix the issue.

Hi @pazrodrigo,

Thank you for following up and letting me know, though unfortunate to hear it didn’t resolve this issue. Custom script modules being included is interesting, and certainly worth testing out as there might very well be a bug somewhere in this case I haven’t come across. I’ll give this some tests and get back to you.

If you have any questions or concerns in the meantime, please let me know!

Best regards,

Kenny

hi @Kenneth_Bates do you have more information about this? I cloned another project and see the same issue. I’ve removed all steps but one, and can now create releases, but if I re add the last removed step the problem returns. I thought the problem was related to using tenant tags, but removing the tags failed to fix it.

I’m sending the CAC setting for the step that works to reproduce the bug:

step "Register EventGrid Topics and Subscriptions - MultiTopic" {

    action {
        action_type = "Octopus.AzurePowerShell"
        properties = {
            Octopus.Action.Azure.AccountId = "#{Tenant.Azure.Octopus.ServicePrincipal}"
            Octopus.Action.Script.ScriptBody = <<-EOT
                #
                # Created by: Eric Stadter, Last Changed:  10/21/2019
                # Update by: Angus Choy, Last Changed:  03/02/2021
                #

                # Enable TLS 1.2
                [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12

                # Variable Setups
                $connectionString = $OctopusParameters["Tenant.CEB.StorageAccountConnectionString"]
                $functionAppName = $OctopusParameters["Tenant.CEB.CaptureFunction.FunctionAppName"]
                $resourceGroupName = $OctopusParameters["Tenant.CEB.CaptureFunction.ResourceGroupName"]
                $resourceGroupLocation = $OctopusParameters["Tenant.CEB.CaptureFunction.ResourceLocation"]
                $eventGridTopicPrefix = $OctopusParameters["Tenant.CEB.Infrastructure.TopicPrefix"]
                $eventGridTopicNames = $OctopusParameters["Tenant.CEB.Infrastructure.TopicNames"]
                $topicRegistrationTenantId = $OctopusParameters["Tenant.CEB.TenantId"]
                $topicRegistrationSubscriptionId = $OctopusParameters["Tenant.CEB.SubscriptionId"]
                $topicRegistrationApplicationId = $OctopusParameters["Tenant.CEB.ApplicationId"]
                $topicRegistrationApplicationIdPassword = $OctopusParameters["Tenant.CEB.ApplicationId.Password"]

                # Get Azure FunctionApp admin token
                $subscriptionId = az account show --query id -o tsv
                $auth = az account get-access-token --output tsv --query accessToken
                $accessTokenHeader = @{ "Authorization" = "Bearer " + $auth }
                $azureRmBaseUri = "https://management.azure.com"
                $azureRmApiVersion = "2016-08-01"
                $azureRmResourceType = "Microsoft.Web/sites"
                $azureRmResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/$azureRmResourceType/$functionAppName"
                $azureRmAdminBearerTokenEndpoint = "/functions/admin/token"
                $adminBearerTokenUri = "$azureRmBaseUri$azureRmResourceId$azureRmAdminBearerTokenEndpoint\?api-version=$azureRmApiVersion"
                $adminBearerToken = Invoke-RestMethod -Method Get -Uri $adminBearerTokenUri -Headers $accessTokenHeader
                $functionAppBaseUri = "https://$functionAppName.azurewebsites.net/admin"
                $masterKeyEndpoint = "/host/systemkeys/_master"
                $masterKeyUri = $functionAppBaseUri + $masterKeyEndpoint
                $adminTokenHeader = @{ "Authorization" = "Bearer $adminBearerToken" }

                # wait for the environment to load up
                Function Wait-Until-Ready {
                    $tries = 0;
                    $done = $false;
                    while ($done -eq $false) {
                        if ($tries -eq 10) {
                            throw 'Giving up, new release not deployed';
                            exit 1;
                        }
                        try {
                            $masterKeyResponse = Invoke-RestMethod -Method Get -Uri $masterKeyUri -Headers $adminTokenHeader;
                            $masterKey = $masterKeyResponse.value
                            if ($masterKey -ne $null) {
                               $done = $true;
                               Write-Host "[INFO] REST API connected OK: $masterKeyUri";
                            } else {
                                $tries = $tries + 1;
                            }
                        } catch {
                        	$tries = $tries + 1;
                            Write-Warning "Reponse empty or http error, retrying...";
                			Write-Warning $_;
                            Write-Host "[INFO] Number of retries: $tries"
                        }
                        Start-Sleep -Seconds 6;
                    }
                }

                Wait-Until-Ready;

                # Get FunctionApp master key
                Write-Host "Acquiring Azure Function app master key..."
                $masterKeyResponse = Invoke-RestMethod -Method Get -Uri $masterKeyUri -Headers $adminTokenHeader
                $masterKey = $masterKeyResponse.value
                if ([string]::IsNullOrEmpty($masterKey))
                {
                    throw New-Object -TypeName System.InvalidOperationException("ERROR - failed acquiring master key.")
                }

                # Get FunctionApp system key
                Write-Host "Acquiring Azure Function app system key..."
                $systemKeyUri = "$functionAppBaseUri/host/systemkeys/eventgrid_extension?code=$masterKey"
                $systemKeyResponse = Invoke-RestMethod -Uri $systemKeyUri -Headers $adminTokenHeader
                $systemKey = $systemKeyResponse.value
                if ([string]::IsNullOrEmpty($systemKey))
                {
                    throw New-Object -TypeName System.InvalidOperationException("ERROR - failed acquiring system key.")
                }

                # Get the appsettings.json path
                $settingsFile = $OctopusParameters["Octopus.Action.Package[CEB_TopicRegistration].ExtractedPath"] + "\appsettings.json"
                $settingsJson = Get-Content $settingsFile | Out-String | ConvertFrom-Json

                $jsonTopicList = @();
                $eventGridTopicNames.Split(',').ForEach({ 
                    $topicFullName = $eventGridTopicPrefix + $_
                	Write-Host "Processing topic $topicFullName ..."

                	# Get the endpoint for the topic
                	$topicEndpoint = az eventgrid topic show -n $topicFullName -g $resourceGroupName --query endpoint --output tsv
                	if ([string]::IsNullOrEmpty($topicEndpoint))
                	{
                		throw New-Object -TypeName System.InvalidOperationException("ERROR - failed acquiring endpoint.")
                	}
                	Write-Host $topicEndpoint

                    # Get key for the topic
                    $eventGridAccessKeyForTopic = az eventgrid topic key list -n $topicFullName -g $resourceGroupName --query key1 --output tsv
                    if ([string]::IsNullOrEmpty($eventGridAccessKeyForTopic))
                    {
                        throw New-Object -TypeName System.InvalidOperationException("ERROR - failed acquiring grid access key.")
                    }

                    # Inject into the working json
                    $jsonTopicList += @{AXTopicName = "$_" ; eventGridTopicName = "$topicFullName" ; eventGridEndpoint = "$topicEndpoint" ; eventGridAccessKey = "$eventGridAccessKeyForTopic"} 
                })
                $settingsJson.CEB.topicConfig.topics = $jsonTopicList
                $settingsJson | ConvertTo-Json -depth 10 | Set-Content $settingsFile

                # Perform Topic Registration from the App
                $exeLocation = $OctopusParameters["Octopus.Action.Package[CEB_TopicRegistration].ExtractedPath"] + "\CEB.TopicRegistration.exe"
                $exeArgList = "-connectionString `"$connectionString`" -tenantId `"$topicRegistrationTenantId`" -subscriptionId `"$topicRegistrationSubscriptionId`" -applicationId `"$topicRegistrationApplicationId`" -applicationIdPassword `"$topicRegistrationApplicationIdPassword`" "

                if (Test-Path $exeLocation)
                {
                    Write-Host "Running Topic Registration App..." 
                    $exeRun = Start-Process -FilePath $exeLocation -ArgumentList $exeArgList -NoNewWindow -Wait -PassThru

                    if ($exeRun.ExitCode -ne 0)
                	{
                   		throw New-Object -TypeName System.InvalidOperationException("ERROR in Topic Registration App - provisioning failed.")
                	}

                    Write-Host "Topic Registration is complete."
                }
                else
                {
                	throw New-Object -TypeName System.InvalidOperationException("ERROR in Topic Registration App - failed to find executable.")
                }

                # Exit
                Write-Host "Process is complete."
                New-OctopusArtifact $settingsFile


            EOT
            Octopus.Action.Script.ScriptSource = "Inline"
            Octopus.Action.Script.Syntax = "PowerShell"
            OctopusUseBundledTooling = "True"
        }
        worker_pool = "Cloud Pool"

        packages "CEB_TopicRegistration" {
            acquisition_location = "Server"
            feed = "#{AX.NugetFeed.Product}"
            package_id = "CEB_TopicRegistration"
            properties = {
                Extract = "True"
                SelectionMode = "immediate"
            }
        }
    }
}

Hi @pazrodrigo,

Thank you kindly for following up, and my apologies for the lack of reply here. I was initially unable to reproduce this issue, and oddly enough with your sample OCL you pasted here I still am not able to. I attempted pasting in the same OCL, also a setup from scratch in a standard (non config as code) project mimicking this step setup and included a custom script module, then cloned the project and converted that clone to CaC. Releases of that cloned-then-converted project are able to be created successfully without issue, so I’m scratching my head at this point.

Would you be willing to export this original project itself, that you’re cloning from then converting that clone to config as code? I’m hoping seeing this bug in action that way and look at the exact data will help illuminate something to narrow down what the issue is.

If you’re happy to provide the project export, you can upload it to to our support files here, which I’ll import locally then attempt the repro steps with that.

I appreciate your report and assistance so far, and I look forward to getting to the bottom of this one.

Best regards,

Kenny

hi @Kenneth_Bates I’ve uploaded two projects that I’ve cloned and migrated to CaC and present the original issue

Thank you for providing those JSON files. Confirming I’ve received them, and have imported one of the two locally in my pre-existing 2022.2 instance, cloned and converted to config as code and can create releases successfully. I’m in the process of standing up a matching version 2022.1.2661 to try to get a clear repro of either project and hopefully we can confirm whether it’s a since-fixed bug or spot anything else in my failure to repro.

I appreciate your patience. If you have any questions as I continue testing, please don’t hesitate to shout out.

Best regards,

Kenny

hi @Kenneth_Bates I’m coming back to this one since it is a blocker for our move to CaC. I have further info that might be related. I’ve cloned the affected project to another space and, at first, creating a release from the UI works, but I couldn’t search for packages. I’ve traced this issue to a variable we use for an external feed, which was referencing the feed id from the original space. Once I added the external feed and fixed the variable value on space #2, I can’t no longer create releases from the UI and the console displays the error below:

Hi @pazrodrigo,

I appreciate you bringing this one back up, and my sincere apologies for the lack of communication. I did some extensive tests in v2022.1.2661 at the time you provided that information, though unfortunately (and strangely) I was completely unable to reproduce. I’ve raised this one back up internally to get some more eyes on this issue, and I’ll reach out as soon as we get anywhere on this one.

Best regards,

Kenny

Hi @pazrodrigo,

Thanks for your patience as I brought this up internally. We’d like to have a look at your Octopus Server log files to get some more information and context around this error message. After reproducing the error once again, would you be willing to grab the server log (C:\Octopus\Logs in standard installs) and upload it to this active secure link?

I look forward to hearing back and getting to the bottom of this one!

Best regards,

Kenny

hi @Kenneth_Bates I’ve just uploaded the log files. I did scan them but did not find any errors. It is a bit verbose so you can filter by searching for space id Spaces-22

Hi @pazrodrigo,

Thank you kindly for sending your server logs. I can confirm we’ve received them, and digging into them now. I’ll let you know any and all updates as soon as possible. :slight_smile:

Best regards,

Kenny

Hi @pazrodrigo,
I would like to check if the script is pulling the feed from the variable correctly. Can you please added this to the script in both the CaC project and the original project:
Write-Host $OctopusParameters["AX.NugetFeed.Product"]
If the values are the same in both projects, we can eliminate that as being the problem. Thanks.
Stephen

hi @stephen.heise , can you please add more detail as to where to add that line? The issue is when creating a release from the UI so I don’t get any chance to run a script as part of the process

At the start of the script body of the “Register EventGrid Topics and Subscriptions - MultiTopic” step should be fine, say before the ‘# Enable TLS 1.2’ line. If you then run it, you should be able to see the output from that step. The very first line of the output will be the value of the AX.NugetFeed.Product variable.