Last active
March 25, 2020 04:59
-
-
Save justinyoo/0516447045d0ef3c606d7e84f0ecd872 to your computer and use it in GitHub Desktop.
Scheduling Posts with GitOps, Durable Functions and GitHub Actions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"owner": "aliencube", | |
"repository": "blog", | |
"issueId": 3, | |
"schedule": "2020-03-25T07:00:00+09:00" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"owner": "devkimchi", | |
"repository": "blog", | |
"issueId": 3, | |
"schedule": "2020-03-25T07:00:00+09:00" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[FunctionName("SetSchedule")] | |
public async Task<HttpResponseMessage> SetSchedule( | |
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "orchestrators/{orchestratorName}")] HttpRequestMessage req, | |
[DurableClient] IDurableOrchestrationClient starter, | |
string orchestratorName, | |
ILogger log) | |
{ | |
var input = await req.Content.ReadAsAsync<EventSchedulingRequest>(); | |
var instanceId = await starter.StartNewAsync<EventSchedulingRequest>(orchestratorName, instanceId: null, input: input); | |
log.LogInformation($"Started orchestration with ID = '{instanceId}'."); | |
return starter.CreateCheckStatusResponse(req, instanceId); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[FunctionName("schedule-event")] | |
public async Task<object> RunOrchestrator( | |
[OrchestrationTrigger] IDurableOrchestrationContext context, | |
ILogger log) | |
{ | |
var input = context.GetInput<EventSchedulingRequest>(); | |
// Set the maximum duration. Max duration can't exceed 7 days. | |
var maxDuration = TimeSpan.Parse(Environment.GetEnvironmentVariable("Duration__Max"), CultureInfo.InvariantCulture); | |
if (maxDuration > threshold) | |
{ | |
return "Now allowed"; | |
} | |
// Get the scheduled time | |
var scheduled = input.Schedule.UtcDateTime; | |
// Get the function initiated time. | |
var initiated = context.CurrentUtcDateTime; | |
// Get the difference between now and schedule | |
var datediff = (TimeSpan)(scheduled - initiated); | |
// Complete if datediff is longer than the max duration | |
if (datediff >= maxDuration) | |
{ | |
return "Too far away"; | |
} | |
await context.CreateTimer(scheduled, CancellationToken.None); | |
var output = await context.CallActivityAsync<object>("CallRepositoryDispatchEvent", input); | |
return output; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[FunctionName("CallMergePrRepositoryDispatchEvent")] | |
public async Task<object> MergePr( | |
[ActivityTrigger] EventSchedulingRequest input, | |
ILogger log) | |
{ | |
var authKey = Environment.GetEnvironmentVariable("GitHub__AuthKey"); | |
var requestUri = $"{Environment.GetEnvironmentVariable("GitHub__BaseUri").TrimEnd('/')}/repos/{input.Owner}/{input.Repository}/{Environment.GetEnvironmentVariable("GitHub__Endpoints__Dispatches").TrimStart('/')}"; | |
var accept = Environment.GetEnvironmentVariable("GitHub__Headers__Accept"); | |
var userAgent = Environment.GetEnvironmentVariable("GitHub__Headers__UserAgent"); | |
this._client.DefaultRequestHeaders.Clear(); | |
this._client.DefaultRequestHeaders.Add("Authorization", authKey); | |
this._client.DefaultRequestHeaders.Add("Accept", accept); | |
this._client.DefaultRequestHeaders.Add("User-Agent", userAgent); | |
var payload = new RepositoryDispatchEventRequest<EventSchedulingRequest>("merge-pr", input); | |
using (var content = new ObjectContent<RepositoryDispatchEventRequest<EventSchedulingRequest>>(payload, this._formatter, "application/json")) | |
using (var response = await this._client.PostAsync(requestUri, content).ConfigureAwait(false)) | |
{ | |
response.EnsureSuccessStatusCode(); | |
} | |
return payload; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[FunctionName("CallPublishRepositoryDispatchEvent")] | |
public async Task<IActionResult> Publish( | |
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "events/publish")] HttpRequest req, | |
ILogger log) | |
{ | |
var input = JsonConvert.DeserializeObject<EventRequest>(await new StreamReader(req.Body).ReadToEndAsync()); | |
var authKey = Environment.GetEnvironmentVariable("GitHub__AuthKey"); | |
var requestUri = $"{Environment.GetEnvironmentVariable("GitHub__BaseUri").TrimEnd('/')}/repos/{input.Owner}/{input.Repository}/{Environment.GetEnvironmentVariable("GitHub__Endpoints__Dispatches").TrimStart('/')}"; | |
var accept = Environment.GetEnvironmentVariable("GitHub__Headers__Accept"); | |
var userAgent = Environment.GetEnvironmentVariable("GitHub__Headers__UserAgent"); | |
this._client.DefaultRequestHeaders.Clear(); | |
this._client.DefaultRequestHeaders.Add("Authorization", authKey); | |
this._client.DefaultRequestHeaders.Add("Accept", accept); | |
this._client.DefaultRequestHeaders.Add("User-Agent", userAgent); | |
var payload = new RepositoryDispatchEventRequest<EventSchedulingRequest>("publish", input); | |
using (var content = new ObjectContent<RepositoryDispatchEventRequest<EventSchedulingRequest>>(payload, this._formatter, "application/json")) | |
using (var response = await this._client.PostAsync(requestUri, content).ConfigureAwait(false)) | |
{ | |
response.EnsureSuccessStatusCode(); | |
} | |
return payload; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Merge PR | |
on: repository_dispatch | |
jobs: | |
merge_pr: | |
name: Merge PR | |
if: github.event.action == 'merge-pr' | |
runs-on: ubuntu-latest | |
steps: | |
- name: Merge PR | |
uses: justinyoo/github-pr-merge-action@v0.8.0 | |
with: | |
authToken: ${{ secrets.GITHUB_TOKEN }} | |
owner: ${{ github.event.client_payload.owner }} | |
repository: ${{ github.event.client_payload.repository }} | |
issueId: '${{ github.event.client_payload.issueId }}' | |
mergeMethod: Squash | |
commitTitle: '' | |
commitDescription: '' | |
deleteBranch: 'true' | |
- name: Send dispatch event for publish | |
shell: bash | |
run: | | |
curl -X POST 'https://${{ secrets.AZURE_FUNCTIONS_NAME }}.azurewebsites.net/api/events/publish' -d '{ "owner": "${{ secrets.OWNER }}", "repository": "${{ secrets.REPOSITORY }}" }' -H "x-functions-key: ${{ secrets.AZURE_FUNCTIONS_KEY }}" -H "Content-Type: application/json" | |
build_and_publish: | |
name: Build and publish | |
if: github.event.action == 'publish' | |
runs-on: ubuntu-latest | |
steps: | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment