Can not add a prompt variable in Code

Hi, we have a project set up in Octopus which I would like to release/deploy programmatically via #C code using Octopus.Client (the project clears a key from a Redis cache on a server). All works great, apart from the fact that I can not add/edit/update (not sure which) the main variable which is KeyName. I am struggling to understand if I am even on the right approach, I think I am close but could you guide me please as atm when I run this code the release fails in Octopus due to no value set in the KeyName variable, so clearly I am not doing it right:

public static bool ClearCacheKey(Logger auditLog, IConfiguration config, string cacheKey)
            var octopusURL = config.GetValue<string>("Octopus:ApiURL");
            var octopusAPIKey = config.GetValue<string>("Octopus:ApiKey");

            var endpoint = new OctopusServerEndpoint(octopusURL, octopusAPIKey);
            var repository = new OctopusRepository(endpoint);

            //var spaceName = "Spaces-1";
            var spaceName = "Default";
            var projectName = "Redis.FlushSpecificKeys";
            var channelName = "Default"; // Channels are not used in the Redis.FlushSpecificKeys project
            var environmentName = "Stage-DATACENTRE";

                // Get the space to work in
                var space = repository.Spaces.FindByName(spaceName);
                auditLog.Info($"Using Space named {space.Name} with id {space.Id}");

                // Create space specific repository
                var repositoryForSpace = repository.ForSpace(space);

                // Get project by name
                var project = repositoryForSpace.Projects.FindByName(projectName);
                auditLog.Info($"Using Project named {project.Name} with id {project.Id}");

                // Get variables
                var variables = repository.VariableSets.Get(project.VariableSetId);

                // Get channel by name
                var channel = repositoryForSpace.Channels.FindByName(project, channelName);
                auditLog.Info($"Using Channel named {channel.Name} with id {channel.Id}");

                // Get environment by name
                var environment = repositoryForSpace.Environments.FindByName(environmentName);
                auditLog.Info($"Using Environment named {environment.Name} with id {environment.Id}");

                // Get the deployment process template
                auditLog.Info("Fetching deployment process template");
                var process = repositoryForSpace.DeploymentProcesses.Get(project.DeploymentProcessId);
                var template = repositoryForSpace.DeploymentProcesses.GetTemplate(process, channel);

                var release = new Octopus.Client.Model.ReleaseResource
                    ChannelId = channel.Id,
                    ProjectId = project.Id,
                    Version = template.NextVersionIncrement,
                    ReleaseNotes = $"Created automatically by Sentinel for cache key {cacheKey}"

                // Set the package version to the latest for each package
                // If you have channel rules that dictate what versions can be used
                //  you'll need to account for that by overriding the selected package version
                auditLog.Info("Getting action package versions");
                foreach (var package in template.Packages)
                    var feed = repositoryForSpace.Feeds.Get(package.FeedId);
                    var latestPackage = repositoryForSpace.Feeds.GetVersions(feed, new[] { package.PackageId }).FirstOrDefault();

                    var selectedPackage = new SelectedPackage
                        ActionName = package.ActionName,
                        Version = latestPackage.Version

                    auditLog.Info($"Using version {latestPackage.Version} for step {package.ActionName} package {package.PackageId}");


                // # Create release
                release = repositoryForSpace.Releases.Create(release, true); // pass in $true if you want to ignore channel rules

                // Re-snapshot the variables so we can modify them
                release = repository.Releases.SnapshotVariables(release);

                var projVarSetId = release.ProjectVariableSetSnapshotId;

                //Get the project variable set using the new snapshot id
                var projSet = repository.VariableSets.Get(projVarSetId);

                //Amend the KeyName var
                projSet.Variables.Where(item => item.Name == "KeyName").FirstOrDefault().Value = cacheKey;
                projSet.Variables.Where(item => item.Name == "KeyName").FirstOrDefault().Scope.Add(ScopeField.Environment, environmentName);
                // # Create deployment
                var deployment = new DeploymentResource
                    ReleaseId = release.Id,
                    EnvironmentId = environment.Id


                auditLog.Info($"Creating deployment for release {release.Version} of project {projectName} to environment {environmentName}");
                deployment = repositoryForSpace.Deployments.Create(deployment);

                return true;
            catch (Exception ex)
                return false;

Anybody at all?

For anyone else stuck, the answers is here, kudos to these guys for sharing cos it is not intuitive, but it works:

Hi @oisin,

Thanks for the update here! And thank you for posting your solution for anyone else who may run into this problem in the future. :slight_smile:

I’m sorry we didn’t manage to get back to you in time with a solution. It’s great to see that you managed to find a relevant conversation for your problem though.

If you have any questions at all on this or run into any further issues, please don’t hesitate to let me know.

Best regards,

@Daniel_Fischer Thanks for coming back to me on this, I would point out that although I found a “solution” which allowed me to achieve the POC I was working on, the solution was based on running a previously ran release of an Octopus project, rather than creating a new one, which would be preferable.

If you do happen to have a suggestion on how to do the following but by creatingt a new release instead I think the community would find that helpful:

var apiKey = "API-12345678910";
var server = "http://localhost:8065";
var environmentName = "MyEnvironment";
var projectName = "MyProject";
var releaseVersion = "0.0.1";

//Add your prompted variables here
var PromptedVariablesForm = new Dictionary<string,string>{
	{ "PromptedVariable1", "foo" },
	{ "PromptedVariable2","bar"}

var endpoint = new OctopusServerEndpoint(server, apiKey);
var repository = new OctopusRepository(endpoint);

var environment = repository.Environments.FindByName(environmentName);
var project = repository.Projects.FindByName(projectName);

var release = repository.Releases.FindOne(x => x.ProjectId == project.Id && x.Version == releaseVersion);
var releaseTemplate = repository.Releases.GetTemplate(release);

var promotion = releaseTemplate.PromoteTo.FirstOrDefault(x => string.Equals(x.Name, environment.Name, StringComparison.InvariantCultureIgnoreCase));

var preview = repository.Releases.GetPreview(promotion);

var formValues = new Dictionary<string, string>();
foreach (var element in preview.Form.Elements)
	var variableInput = element.Control as VariableValue;
	if(variableInput == null){
	string val;
	if(PromptedVariablesForm.TryGetValue(variableInput.Name, out val)){
		formValues.Add(element.Name, val);

//creating the deployment object
var deployment = new DeploymentResource
	ReleaseId = release.Id,
	ProjectId = project.Id,
	EnvironmentId = environment.Id,
	FormValues = formValues

//Deploying the release in Octopus
var result = repository.Deployments.Create(deployment);

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.