Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert workflow file to AgentJobRequestMessage #1014

Closed
ba32107 opened this issue Mar 18, 2021 · 2 comments
Closed

Convert workflow file to AgentJobRequestMessage #1014

ba32107 opened this issue Mar 18, 2021 · 2 comments

Comments

@ba32107
Copy link

ba32107 commented Mar 18, 2021

Hi,

Is there any way to convert a workflow file to an AgentJobRequestMessage that the Runner can handle? My understanding is that the Runner continuously polls GitHub, and whenever there is a new job to be executed, GitHub will return a JSON that is serialized into a AgentJobRequestMessage instance, which contains all the workflow details, such as steps, environment variables, inputs, etc.

My use case is very similar as described in #494. Whenever a new job request arrives, I want to check the github.ref value, and if it does not equal the main branch of the repo, I want to dynamically "replace" the contents of the workflow with the one from the main branch. This would allow my to protect the workflow file from undesired modifications on the branch.

In order to achieve this, I'd need to modify the AgentJobRequestMessage object, but since the JSON is constructed on the GitHub side, there is no easy and obvious way for me to say "pick another workflow file, not this one". So I'd need a logic that "converts" a workflow file into an AgentJobRequestMessage.

I could implement this myself, but this wouldn't be a long term sustainable solution. Is there any way of asking GitHub to serialize a given revision of a workflow file into the correct format?

Thanks,
Balazs

@ChristopherHX
Copy link
Contributor

I could implement this myself

Well I did it already some month ago. Here is a part of it to convert jobsteps from a yaml file.
Just replace the steps of AgentJobRequestMessage with the result of ConvertStepsFromYaml. I used as much api as I found in the source code. Do anything what you want with this snipped.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using GitHub.DistributedTask.ObjectTemplating;
using GitHub.DistributedTask.ObjectTemplating.Tokens;
using GitHub.DistributedTask.Pipelines;
using GitHub.DistributedTask.Pipelines.ObjectTemplating;

namespace Sample {
    public class Program
    {
        public static IEnumerable<JobStep> ConvertStepsFromYaml(string fileRelativePath) {
            var templateContext = new TemplateContext(){
                CancellationToken = CancellationToken.None,
                Errors = new TemplateValidationErrors(10, 500),
                Memory = new TemplateMemory(
                    maxDepth: 100,
                    maxEvents: 1000000,
                    maxBytes: 10 * 1024 * 1024),
                TraceWriter = new EmptyTraceWriter(),
                Schema = PipelineTemplateSchemaFactory.GetSchema()
            };
            var token = default(TemplateToken);
            // Get the file ID
            var fileId = templateContext.GetFileId(fileRelativePath);
            // Read the file
            var fileContent = System.IO.File.ReadAllText(fileRelativePath);
            using (var stringReader = new StringReader(fileContent))
            {
                var yamlObjectReader = new YamlObjectReader(fileId, stringReader);
                token = TemplateReader.Read(templateContext, "steps", yamlObjectReader, fileId, out _);
            }
            var steps = PipelineTemplateConverter.ConvertToSteps(templateContext, token);

            foreach (var step in steps)
            {
                step.Id = Guid.NewGuid();
            }
            return steps.Cast<JobStep>();
        }

        public static void Main(string[] args)
        {
            var steps = ConvertStepsFromYaml("path/to/yamlfile/with/steps.yml");
        }
    }
}

A yaml file with steps

- name: Step 1
  run: |
    echo Step 1
- name: Step 2
  run: |
    echo Step 2

I hope this helps someone :)

@hross
Copy link
Contributor

hross commented Mar 30, 2021

We don't currently support a way to do this on the runner. We have some work in progress to look into better support for policies like this, but it's a larger project than just the runner. I will provide this feedback to our PMs.

@hross hross closed this as completed Mar 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants