



  

<!DOCTYPE html>
<html
  lang="en"
  
  data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
  data-a11y-animated-images="system" data-a11y-link-underlines="true"
  
  >




  <head>
    <meta charset="utf-8">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
  <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
  <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
  <link rel="preconnect" href="https://github.githubassets.com" crossorigin>
  <link rel="preconnect" href="https://avatars.githubusercontent.com">

<script type="importmap">{"imports":{"react":"https://github.githubassets.com/assets/react-e27d1b3e03961e68.js","react-dom":"https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js","react-dom/client":"https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js","react-is":"https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js","react-reconciler":"https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js","react/compiler-runtime":"https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js","react/jsx-dev-runtime":"https://github.githubassets.com/assets/react-jsx-dev-runtime-ea55d68667d559e5.js","react/jsx-runtime":"https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js","scheduler":"https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js"}}</script>
<meta name="react-profiling" content="0" data-turbo-transient="true" />
<meta name="react-import-map" content="react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@777f63f87cd0" data-turbo-track="reload" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-e27d1b3e03961e68.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js" />

  


  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-0f910d8806d5761b.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-a7abd4d4c49ac593.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-5fc4c4a9cb41e596.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-ed0cee9214dedabd.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-78a2491d538dab5a.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-c26b63d7c532d0a2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-a6f60cea68c08405.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-f66faf28b2ea18b6.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-6701f6218c53cf5b.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-7037fa46ae124d97.css" />

  <style type="text/css">
    :root {
      --tab-size-preference: 4;
    }

    pre, code {
      tab-size: var(--tab-size-preference);
    }
  </style>

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-97df7784617ce1ea.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-9be9fe6313f476af.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-62747e27e61258dc.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-7a418ea859d1654d.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-72bd7d974b5ac1cc.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-4c5c0895f723f870.css" />

  

  <script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_caches_react_shell","actions_enable_background_steps","actions_new_hosted_runner_image_select_sizes_and_versions","actions_runners_react_shell","activity_diff_file_tree","activity_repos_file_tree","activity_repos_overview_header","activity_repos_overview_sidebar","agent_author_search_expansion","agent_author_search_expansion_ui_pulls","alternate_user_config_repo","async_conversion_coverage_enabled","billing_billable_licenses_cost_center_bucket_fix","billing_budget_expiration","billing_cost_center_list_assigned_resources","billing_discount_threshold_notification","code_quality_enablement_banner_targeting","code_quality_remove_preview","code_view_raf_sticky_lines","codespaces_prebuild_region_target_update","coding_agent_third_party_model_ui","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_automation_repo_mcp_servers","copilot_automations_pagination","copilot_base_model_policy_row","copilot_chat_auto_mode_v2","copilot_chat_clear_model_selection_for_default_change","copilot_chat_early_task_provisioning","copilot_chat_persist_session_drafts","copilot_chat_vision_dotcom_chat_ga_gate","copilot_css_textarea_autosize","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_removal_on_marketplace","copilot_fix_failed_workflows_all_skus","copilot_hide_hovercard","copilot_immersive_task_hyperlinking","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_merge_fix_ci","copilot_mission_control_agent_merge_resolve_conflicts","copilot_mission_control_awps_batching","copilot_mission_control_early_stop","copilot_mission_control_managed_sandbox_environments","copilot_mission_control_needs_attention","copilot_mission_control_reasoning_effort","copilot_mission_control_sandbox_remote_bypass","copilot_mission_control_task_alive_updates","copilot_mission_control_task_sharing","copilot_org_policy_page_focus_mode","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_swe_agent_authorization_status_ui","copilot_swe_agent_automation_resource_scoped_writes","copilot_swe_agent_discussion_comment_trigger","copilot_swe_agent_discussion_opened_trigger","copilot_swe_agent_discussion_updated_trigger","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_issue_assigned_trigger","copilot_swe_agent_issue_comment_trigger","copilot_swe_agent_issue_labeled_trigger","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_pull_request_assigned_trigger","copilot_swe_agent_pull_request_comment_trigger","copilot_swe_agent_pull_request_labeled_trigger","copilot_swe_agent_pull_request_merged_trigger","copilot_swe_agent_pull_request_opened_trigger","copilot_swe_agent_pull_request_ready_for_review_trigger","copilot_swe_agent_pull_request_review_requested_trigger","copilot_swe_agent_pull_request_review_submitted_trigger","copilot_swe_agent_pull_request_synchronize_trigger","copilot_swe_agent_sub_issue_added_trigger","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_task_scoped_alive_channel","copilot_token_based_billing","copilot_unconfigured_is_inherited","copilot_user_can_upgrade_plan_field","copilot_workbench_sunset_redirect","dashboard_agents_module_auth_token_check","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","fgpat_permissions_selector_redesign","glc_code_quality_repo_settings_workflow_config","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","in_product_messaging_datadog_monitoring","ipm_ubb_individual_budget_banner","issue_fields_multi_select","issue_inline_avatars","issue_pinned_views","issue_pinned_views_team_vs_personal","issue_relative_time_micro","issues_expanded_file_types","issues_hide_closed_sub_issues","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","labels_archiving","labels_archiving_info","landing_pages_ninetailed","lifecycle_label_name_updates","marketing_cookie_consent_banner","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_queue_restricted_pushers_warning","merge_status_header_feedback","milestone_closed_issues_prioritization","milestone_show_data_router","octocaptcha_origin_optimization","primer_react_css_anchor_positioning","primer_react_merged_forwarded_refs","prs_copilot_app_open_action","prs_css_anchor_positioning","pull_request_copilot_attribution_header","pull_request_overview_merge_control","pull_request_overview_panel_edit_description","pull_request_persister","pull_request_stacks_navigation_shortcuts","pull_request_virtualization_image_estimate","pull_request_virtualization_loader_batching","pull_request_virtualization_scroll_compensation","pull_request_virtualization_scroll_intent","quick_search_lazy_suggestions","react_blob_isolate_code_lines","react_blob_ssr_content_visibility","react_data_router_tanstack_allowed","react_logged_out_repository_header","react_query_props_with_key","react_sandbox_future_tanstack","repo_app_turbo","repo_issues_sidebar_layout","repo_pulls_dashboard_declutter","repo_pulls_dashboard_ga","repo_pulls_dashboard_persistence","repo_pulls_dashboard_sidebar_links","repos_contributors_limited_default_range","review_involves_filter","rule_ignored_file_paths","rulesets_actor_list_editor","sample_network_conn_type","security_center_artifact_filters_popover","see_who_reacted","semantic_similarity_duplicate_issue_detection","session_logs_ungroup_reasoning_text","set_sha256_on_repo_creation_form","site_banner_desktop_copilot_app","site_ghca_pixel_mona","site_github_app_ga_page","site_github_app_ga_page_highlight","site_github_app_mobile_native_share","site_global_banner_dev_days_attendee","site_global_nav_spark_models_removed","speculation_rules_ui_service","suggest_custom_property_values_copilot","suppress_automated_browser_vitals","swp_forms_disable_octocaptcha","thread_resolution_reason","update_issue_suggestions","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workstream_plugin_bootstrap"],"githubDomain":"https://github.com","copilotApiOverrideUrl":"https://api.githubcopilot.com","cmcApiUrl":"https://api.github.com/cmc_internal/api"}</script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/high-contrast-cookie-b752d992928a526c.js"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-runtime-9a73c70656d68424.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-foundation-2f08c823163591a8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-runtime-633ad94fa06c334b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fetch-utilities-0fb4c544a797ec0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ser-7c872b58ac9f1b39.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tp-7e9817cf5c068979.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/environment-13581bcf3014690c.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-runtime.bef03fb24bb03be8.module.css" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/catalyst-52ed81112a548e10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/selector-observer-e8810f64c443fb9b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/relative-time-element-0417f617ad744a0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/by-9da36843ba9d191d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ja9-9a1160b939f2cd52.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3h-55903cf2303047ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hk-f1498fec45311acd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jz5-7aa1ff0a0e750f41.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hj-1d800d09e9a8720a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j0-9697c1c8f5cbf523.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/github-elements-d1f4ae17ff6251ca.js" defer="defer"></script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/element-registry-858cf81e79c970c4.js" defer="defer"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/runtime-helpers-5e0b3ae3c4036207.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/aria-live-d2ef8fd55d6f71f9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hotkey-b1ee53c2200b172a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-core-7bf7b9d689fe3d10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a9-ca3bc10b816bcc1f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ur-21ec1e439ee2d87c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4t-4c39f7195fc42cc8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pb-53cfff089eaac51b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6n-afcf86ccabc4cad2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zj-4d9cf83cf08e1643.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wo-6991af5b3829ffe8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/nfv-a6c14301d3ea6d67.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b5-a2fde30ce0c692b9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sw-9d0489dbf9a9c942.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ttf-7d5abe1b447ced2c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sj-c7a44023ee90d468.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0pd-c46d8dfae89c2b64.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/behaviors-3667c70ab42d85ea.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.255cab819a92f7e1.module.css" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-menu-cda96ed9f534b94e.js" defer="defer"></script>
  
  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/primer-react-8503588299651923.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ncx-66e64888bc4615bb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qmp-c7cfba40cf5a93b0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j6-148a74299e5a01ab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t7l-a9404625ec30bbc7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4u-8f9f1d6be01d6a22.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/s0-68d09e5e8a80cb94.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y5-0cb3f75cec297941.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/n4u-cd9039ad946274ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j8s-00bd469c4017a543.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/la-27679061f16e1495.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/iu-2d03f5e6d4fdd54d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gru-2b0fac8887ff8c57.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a0-234e967e7c6d22ce.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/vy-3c8ad63dc4e1c197.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gb-38d1cc3e31e45c0b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gzu-6ad9a0527a5d7afd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bi-3a42b8714e06c4d0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tu1-37e16844272ddefa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b1-ac66ededed061993.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gmn-1e5497c041b66231.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0l5-d1b2a63015b5eb6d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/c2-e85522be441acf73.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/f9-baf0a4193779952e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sp-87dce99c82a27004.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zkm-116b01b8485bbe3f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/og-518d12c9e011601d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b9-947db365ea875cfa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/14-8c7b4ad3c845664c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dsj-2e7d883cb843e9e6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ecu-ce5620d05ce1e270.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/20-f43eb09c2be69457.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/du-6607da3b8b579202.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ql0-107312645ac2b72d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-fa7cdc0f7656d876.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p0l-fe491d943adf7508.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/v1e-d099d9fd21ad25e5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fn-7b298a45c55fb6fb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7cw-6e493a20eaaa04b5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ok-290e4b9465ba9c5b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6d-ca6d584a0fd6368c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y8-a7bd39adbab9c4a4.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xc-3fd4a2e7dcbad8e2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/vj-8ecd8f7276cf657c.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-view-09072f90cc6bbf08.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/xc.de2b1dde0494f261.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-view.692152e2b9cc4f38.module.css" />


  <title>branch-deploy/docs/examples.md at main · github/branch-deploy · GitHub</title>



  <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient>
  <meta name="route-controller" content="blob" data-turbo-transient>
  <meta name="route-action" content="show" data-turbo-transient>
  <meta name="fetch-nonce" content="v2:ce358de0-f3be-43f7-fb54-ba1a8d2cad17">

    
  <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">


  <meta name="request-id" content="E9F2:1AF2DA:656F:838F:6AC79F18" data-pjax-transient="true"/><meta name="html-safe-nonce" content="17bd3d9b3a134dc9858c722dbbd937dd81f33f66101dd3a4c62ff14bbc53c65a" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFOUYyOjFBRjJEQTo2NTZGOjgzOEY6NkFDNzlGMTgiLCJ2aXNpdG9yX2lkIjoiMjQ5NjEwMDQwMjgzNjUxMjUzNiIsInJlZ2lvbl9lZGdlIjoiZnJhIiwicmVnaW9uX3JlbmRlciI6ImZyYSJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="ebcb15d8f9c0b60545a8b597af8e2895b5f0ddc2ac65df5089ee917a314183dc" data-pjax-transient="true"/>


    <meta name="hovercard-subject-tag" content="repository:486614111" data-turbo-transient>


  <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" />
  

  <meta name="selected-link" value="repo_source" data-turbo-transient>
  <link rel="assets" href="https://github.githubassets.com/">

    <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">

<meta name="octolytics-url" content="https://collector.github.com/github/collect" />





  <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" />

  




    <meta name="user-login" content="">

  

    <meta name="viewport" content="width=device-width">

    

      <meta name="description" content="Enabling Branch Deployments through IssueOps with GitHub Actions - If you find this project useful, give it a star! ⭐️  - branch-deploy/docs/examples.md at main · github/branch-deploy">

      <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">

    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
    <meta property="fb:app_id" content="1401488693436528">
    <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/github/branch-deploy/blob/main/docs/examples.md" />

      <meta name="twitter:image" content="https://repository-images.githubusercontent.com/486614111/aaad4e0a-3543-45d1-a4c8-38c576549639" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="branch-deploy/docs/examples.md at main · github/branch-deploy" /><meta name="twitter:description" content="Enabling Branch Deployments through IssueOps with GitHub Actions - If you find this project useful, give it a star! ⭐️  - github/branch-deploy" />
  <meta property="og:image" content="https://repository-images.githubusercontent.com/486614111/aaad4e0a-3543-45d1-a4c8-38c576549639" /><meta property="og:image:alt" content="Enabling Branch Deployments through IssueOps with GitHub Actions - If you find this project useful, give it a star! ⭐️  - github/branch-deploy" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="branch-deploy/docs/examples.md at main · github/branch-deploy" /><meta property="og:url" content="https://github.com/github/branch-deploy/blob/main/docs/examples.md" /><meta property="og:description" content="Enabling Branch Deployments through IssueOps with GitHub Actions - If you find this project useful, give it a star! ⭐️  - github/branch-deploy" />
  




      <meta name="hostname" content="github.com">



        <meta name="expected-hostname" content="github.com">


  <meta http-equiv="x-pjax-version" content="fb7c1a78ff3df74010852610d444f39f336314c49974260056673b37cb5c3dcf" data-turbo-track="reload">
  <meta http-equiv="x-pjax-csp-version" content="c4a65e47b0c850e1157ae8e66298070851d7e3b558038de5a3b4ff7a93e630ed" data-turbo-track="reload">
  <meta http-equiv="x-pjax-css-version" content="1ff3f1d4e1abd61f6f135b47d3b815e2f7169f8dd418f0118c6b1cf4de6cbc86" data-turbo-track="reload">
  <meta http-equiv="x-pjax-js-version" content="ee955a281d040625f2eae3a332143eb077629f00badcd1f7db06f3e2077289fd" data-turbo-track="reload">

  <meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">

      <meta name="turbo-cache-control" content="no-cache" data-turbo-transient>

    <meta data-hydrostats="publish">

  <meta name="go-import" content="github.com/github/branch-deploy git https://github.com/github/branch-deploy.git">

  <meta name="octolytics-dimension-user_id" content="9919" /><meta name="octolytics-dimension-user_login" content="github" /><meta name="octolytics-dimension-repository_id" content="486614111" /><meta name="octolytics-dimension-repository_nwo" content="github/branch-deploy" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="486614111" /><meta name="octolytics-dimension-repository_network_root_nwo" content="github/branch-deploy" />
  



    

    <meta name="turbo-body-classes" content="logged-out env-production page-responsive">
  <meta name="disable-turbo" content="false">


  <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">


  <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">

  <meta name="release" content="4d24b21ed0f061a3af200f24329cea0e46e0d0b7" data-turbo-track="reload">
  <meta name="ui-target" content="canary-1">

  <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000">
  <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
  <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon">

<meta name="theme-color" content="#1e2327">
<meta name="color-scheme" content="light dark" />


  <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">

  </head>

  <body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
    <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
      <div id="__primerPortalRoot__" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
      

    <div class="position-relative header-wrapper js-header-wrapper ">
      <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a>

      <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full">
    <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span>
</span>      
      <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qc-1bbbe8787ea1cd4b.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-5b9993bd3e287842.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.61e4931d588777a1.module.css" />

<react-partial
  partial-name="keyboard-shortcuts-dialog"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>





      

          <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-install-banner-partial-bf36345e611e5f2e.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-install-banner-partial.7698961548f22204.module.css" />

<react-partial
  partial-name="app-install-banner-partial"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>


          

                <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2l-944c857d28550aad.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/rwd-1b867d62d1bceeac.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fz-e662bc3745e171e7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jag-3559ee48016881a2.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3d-7f22b36f29a9dd94.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tua-4998592d21eb16f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/8i-a426a972ffda487c.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/marketing-header-4293067a42c00c59.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-brand-css.05b219cdb8e80c43.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/8i.572bfb17540c2298.module.css" />

<react-partial
  partial-name="marketing-header"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"color_mode":"dark","logged_in":false,"marketing_page":false,"home_path":"/","login_path":"/login?return_to=https%3A%2F%2Fgithub.com%2Fgithub%2Fbranch-deploy%2Fblob%2Fmain%2Fdocs%2Fexamples.md","signup_path":"/signup?ref_cta=Sign+up\u0026ref_loc=header+logged+out\u0026ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow\u0026source=header-repo\u0026source_repo=github%2Fbranch-deploy","signup_enabled":true,"is_signup_controller":false,"show_search_and_nav":true,"hide_search":false,"private_mode_enabled":false,"should_use_dotcom_links":true,"auth_hydro_click":"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/github/branch-deploy/blob/main/docs/examples.md\",\"user_id\":null}}","auth_hydro_click_hmac":"062391e5e84c56daaeebf052e84fec1765b5ef41c7da45b69ccee94bdcfe63c8","overlay":false,"fixed":false}}</script>
  <div data-target="react-partial.reactRoot"><div data-color-mode="dark" data-light-theme="light" data-dark-theme="dark"><header class="MarketingHeader-module__root__Tk7n3 HeaderMktg header-logged-out" role="banner" data-marketing-header="true" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-is-top="true"><h2 class="MarketingHeader-module__visuallyHidden__sqKsl">Navigation Menu</h2><button type="button" class="MarketingHeader-module__backdrop__sw4RU" aria-label="Close navigation menu"></button><div class="MarketingHeader-module__bar__mBSyE"><div class="MarketingHeader-module__topRow__yeury"><div class="MarketingHeader-module__toggleSlot__hDxbh"><button type="button" class="HeaderMenuToggle-module__toggle__i8EiC" aria-label="Toggle navigation" aria-expanded="false"><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span></button></div><a href="/" aria-label="Homepage" class="HeaderLogo-module__logo__UFyHI" data-analytics-event="{&quot;action&quot;:&quot;homepage&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;logo&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;homepage_link_logo_header&quot;}"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github" viewBox="0 0 24 24" width="32" height="32" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path></svg></a><div class="AuthCTAs-module__mobileActions__NNzeV"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fgithub%2Fbranch-deploy%2Fblob%2Fmain%2Fdocs%2Fexamples.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/github/branch-deploy/blob/main/docs/examples.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="062391e5e84c56daaeebf052e84fec1765b5ef41c7da45b69ccee94bdcfe63c8"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_3dd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_3dd_">Appearance settings</div></div></div><div class="MarketingHeader-module__menu__GIy3y"><div class="MarketingHeader-module__menuWrapper__owstH"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_nd_">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5knd_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>GitHub Copilot</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Write better code with AI</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/ai/github-app" data-analytics-event="{&quot;action&quot;:&quot;github_copilot_app&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_app_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"></path></svg>GitHub Copilot app</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Direct agents from issue to merge</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.52 1.12a3.578 3.578 0 0 1 6.078 2.98 3.578 3.578 0 0 1 2.982 6.08l-3.292 3.293a.252.252 0 0 0 0 .354l.843.843a.749.749 0 1 1-1.06 1.06l-.844-.843a1.75 1.75 0 0 1 0-2.474L13.52 9.12a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0L7.731 9.03A.75.75 0 0 1 6.67 7.97l2.85-2.85a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0l-4.799 4.8A.75.75 0 0 1 .72 5.92Z"></path><path d="M7.52 3.12a.749.749 0 1 1 1.06 1.06L5.731 7.03A2.079 2.079 0 0 0 8.67 9.97l2.85-2.85a.749.749 0 1 1 1.06 1.06l-2.849 2.85A3.578 3.578 0 0 1 4.67 5.97Z"></path></svg>MCP Registry</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Integrate external tools</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9knd_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path></svg>Actions</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Automate any workflow</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg>Codespaces</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Instant dev environments</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Issues</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Plan and track work</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg>Code Review</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Manage code changes</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-quality" data-analytics-event="{&quot;action&quot;:&quot;code_quality&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_quality_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codescan-checkmark NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.28 6.28a.75.75 0 1 0-1.06-1.06L6.25 8.19l-.97-.97a.75.75 0 0 0-1.06 1.06l1.5 1.5a.75.75 0 0 0 1.06 0l3.5-3.5Z"></path><path d="M7.5 15a7.5 7.5 0 1 1 5.807-2.754l2.473 2.474a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2.474-2.473A7.472 7.472 0 0 1 7.5 15Zm0-13.5a6 6 0 1 0 4.094 10.386.748.748 0 0 1 .293-.292 6.002 6.002 0 0 0 1.117-6.486A6.002 6.002 0 0 0 7.5 1.5Z"></path></svg>Code Quality</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enforce quality at merge</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dknd_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>Code security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Secure your code as you build</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>Secret protection</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_hknd_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Why GitHub</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Blog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Changelog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all features</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_17d_">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_17d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5l7d_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Enterprises</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Small and medium teams</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Startups</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9l7d_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">App Modernization</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevSecOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">CI/CD</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all use cases</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dl7d_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dl7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Healthcare</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Financial services</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Manufacturing</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Government</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all industries</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all solutions</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_1nd_">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_1nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5lnd_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">AI</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Software Development</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all topics</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9lnd_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer stories</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Events &amp; webinars</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Ebooks &amp; reports</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Business insights</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Skills</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dlnd_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dlnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer support</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Community forum</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trust center</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources" data-analytics-event="{&quot;action&quot;:&quot;view_all_resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_resources_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all resources</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_27d_">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_27d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5m7d_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/open-source/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1Zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105ZM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75Z"></path></svg>GitHub Sponsors</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Fund open source developers</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9m7d_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security Lab</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Maintainer Community</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://stars.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_stars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_stars_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Stars</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Archive Program</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dm7d_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dm7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Topics</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trending</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_2nd_">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_2nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5mnd_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.122.392a1.75 1.75 0 0 1 1.756 0l5.003 2.902c.83.481.83 1.68 0 2.162L8.878 8.358a1.75 1.75 0 0 1-1.756 0L2.119 5.456a1.251 1.251 0 0 1 0-2.162ZM8.125 1.69a.248.248 0 0 0-.25 0l-4.63 2.685 4.63 2.685a.248.248 0 0 0 .25 0l4.63-2.685ZM1.601 7.789a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0L1.874 8.814A.75.75 0 0 1 1.6 7.789Zm0 3.5a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0l-5.248-3.044a.75.75 0 0 1-.273-1.025Z"></path></svg>Enterprise platform</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9mnd_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>Copilot for Business</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg>Premium Support</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></span></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="MarketingNavigation-module__navLink__hUomM">Pricing</a></li></ul></nav><div class="MarketingHeader-module__ctaContainer__tBmPz"><div class="HeaderSearch-module__searchSlot__oVOUS"><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderSearch-module__trigger__zsF9q" type="button" aria-haspopup="dialog" aria-expanded="false" aria-label="Search or jump to, type / to search" data-analytics-event="{&quot;action&quot;:&quot;searchbar&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;context&quot;:&quot;global&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"><span class="HeaderSearch-module__content__kMpxU"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search HeaderSearch-module__icon__wcrHX" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg><span class="HeaderSearch-module__label__d1iWG">Search</span><kbd class="HeaderSearch-module__kbd__HNG0o" aria-hidden="true">/</kbd></span></span></span></button><div class="d-none"></div></div><div class="AuthCTAs-module__signInWrap__q2P60"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq AuthCTAs-module__desktopActionGap__UZuXT AuthCTAs-module__hiddenBelowLg__BfKBw" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fgithub%2Fbranch-deploy%2Fblob%2Fmain%2Fdocs%2Fexamples.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/github/branch-deploy/blob/main/docs/examples.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="062391e5e84c56daaeebf052e84fec1765b5ef41c7da45b69ccee94bdcfe63c8"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a></div><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--secondary___gHnw_ Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=github%2Fbranch-deploy" data-analytics-event="{&quot;action&quot;:&quot;sign_up&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_up_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/github/branch-deploy/blob/main/docs/examples.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="062391e5e84c56daaeebf052e84fec1765b5ef41c7da45b69ccee94bdcfe63c8"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-secondary___eJ0_a">Sign up</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_fbd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_fbd_">Appearance settings</div></div></div></div></div><div class="MarketingHeader-module__bottomBorder__uZT38" aria-hidden="true"></div></header></div></div>
</react-partial>



      <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
  
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>

    <button id="icon-button-f7efe160-b645-4148-bc72-4379b6828d5a" aria-labelledby="tooltip-555ab8f5-290d-4a30-9df2-cec5798d039e" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-555ab8f5-290d-4a30-9df2-cec5798d039e" for="icon-button-f7efe160-b645-4148-bc72-4379b6828d5a" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>


  
</div>
    </div>

  <div id="start-of-content" class="show-on-focus"></div>








    <div id="js-flash-container" class="flash-container" data-turbo-replace>






  <template class="js-flash-template">
    
<div class="flash flash-full   {{ className }}">
  <div >
    <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    <div aria-atomic="true" role="alert" class="js-flash-alert">
      
      <div>{{ message }}</div>

    </div>
  </div>
</div>
  </template>
</div>


    






  <div
    class="application-main "
    data-commit-hovercards-enabled
    data-discussion-hovercards-enabled
    data-issue-and-pr-hovercards-enabled
    data-project-hovercards-enabled
  >
        <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
    <main id="js-repo-pjax-container" >
      
      
    


    








  

    <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ym-1a7ce813a378e1f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mn-bb458474353a279e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t5-26d19272bbf73ca3.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2d5-9abb2f6ba5c935d0.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/24-b11e1c4108322883.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mr-816ede0c8a7894cc.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dgq-11d4dc359ebe6dff.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7w-740b4e942974ccba.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/we-c9f93392098ad6c9.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/775-1b2de555e77bf6c5.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bn-fcef0645a47703fc.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xgw-6c6cb7b2ed77f52e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ge-ca1c0ba8656f9680.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/9f-196b81a07eb269eb.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/global-nav-bar-32802bed2fa78fdb.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-nav-bar.a955762f6a6305f1.module.css" />

<react-partial
  partial-name="global-nav-bar"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"contextRegion":{"crumbs":[{"crumb_type":"organization","label":"github","is_root":false,"href":"/github"},{"crumb_type":"repository","label":"branch-deploy","is_root":false,"href":"/github/branch-deploy"}],"localNavigation":[{"id":"code","icon":"code","label":"Code","href":"/github/branch-deploy","selectedLinks":["repo_source","repo_downloads","repo_commits","repo_releases","repo_tags","repo_branches","repo_packages","repo_deployments","repo_attestations"],"popoverTarget":false,"commandId":"repositories:go-to-code","reactNav":{"appTarget":"code-view","anchor":"code-view-repo-link"},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"issues","icon":"issue-opened","label":"Issues","href":"/github/branch-deploy/issues","selectedLinks":["repo_issues","repo_labels","repo_milestones"],"count":14,"popoverTarget":false,"commandId":"repositories:go-to-issues","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"pull-requests","icon":"git-pull-request","label":"Pull requests","href":"/github/branch-deploy/pulls","selectedLinks":["repo_pulls","checks"],"count":7,"popoverTarget":false,"commandId":"repositories:go-to-pull-requests","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"actions","icon":"play","label":"Actions","href":"/github/branch-deploy/actions","selectedLinks":["repo_actions"],"popoverTarget":false,"commandId":"repositories:go-to-actions","reactNav":{"appTarget":"actions-workflows","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"security-and-quality","icon":"shield","label":"Security and quality","href":"/github/branch-deploy/security","selectedLinks":["security","overview","alerts","policy","token_scanning","code_scanning"],"count":0,"popoverTarget":false,"commandId":"repositories:go-to-security","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"insights","icon":"graph","label":"Insights","href":"/github/branch-deploy/pulse","selectedLinks":["repo_graphs","repo_contributors","dependency_graph","dependabot_updates","pulse","people","community"],"popoverTarget":false,"commandId":"repositories:go-to-insights","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}}],"localNavigationUpdateChannel":null,"selectedLink":"repo_source"},"owner":null,"headerLogo":{"href":"/","aria-label":"Homepage "},"notifications":{"indicatorMode":"disabled","websocketChannel":null,"fetchIndicatorSrc":"/notifications/indicator","fetchIndicatorEnabled":false},"issues":{"href":"/issues"},"pulls":{"href":"/pulls"},"contributedRepos":{"href":"/repos"},"copilot":{"show":false,"showAgentsButton":false,"showRelaunchAnnouncement":false,"copilotChatUrl":null,"copilotApiUrl":"https://api.githubcopilot.com"},"search":{"show":true,"showCommandPalette":false,"isSearchPage":false,"isJumpToSearch":false,"searchContext":{"scope":"repo:github/branch-deploy","current_repo_name":"branch-deploy","current_repo_nwo":"github/branch-deploy","current_repo_org":"github","user_id":"github"}},"commandPalette":null,"enterpriseBar":{"show":false},"globalTransactionalMessage":[],"payloadsUrl":"/_global-navigation/payloads.json?can_toggle_site_admin_and_employee_status=0\u0026is_admin_mode_on=0\u0026is_ui_opted_out=0\u0026show_ui_opt_out=0\u0026v=6","contextRegionUrl":"/_global-navigation/context-region.json"}}</script>
  <div data-target="react-partial.reactRoot"><header aria-label="Global navigation menu" data-component="Stack" class="GlobalNav styles-module__appHeader__YzYWk prc-Stack-Stack-UQ9k6" data-gap="none" data-direction="vertical" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="none"><div data-component="Stack" class="prc-Stack-Stack-UQ9k6" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="center" data-padding="none"><div data-testid="top-nav-center" data-component="Stack" class="styles-module__center__R3QRv styles-module__withLocalNavigation__rjTJ_ GlobalNavBar-module__loggedOut__Jv1rk prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="normal"><nav class="styles-module__contextRegion__VbSp2 prc-Breadcrumbs-BreadcrumbsBase-3Gb-B" aria-label="Breadcrumbs" data-overflow="menu" data-variant="normal" data-component="Breadcrumbs"><ol class="prc-Breadcrumbs-BreadcrumbsList-BKjpe"><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/github" data-discover="true"><span class="">github</span></a></li><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/github/branch-deploy" data-discover="true"><span class="styles-module__contextCrumbLast__tI2e3">branch-deploy</span></a></li></ol></nav></div><div data-testid="top-nav-right" data-component="Stack" class="styles-module__right__mlBQg styles-module__withLocalNavigation__rjTJ_ styles-module__rightWithResponsiveCreateButton__SKn2W prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="start" data-padding="normal"></div></div><h2 class="prc-src-InternalVisuallyHidden-2YaI6">Repository navigation</h2><nav class="prc-components-UnderlineWrapper-eT-Yj prc-UnderlineNav-UnderlineWrapper-GWONT LocalNavigation-module__LocalNavigation__b0Xc0" aria-label="Repository" data-variant="inset" data-overflow-mode="wrap" data-hide-icons-breakpoint="medium"><ul class="prc-UnderlineNav-ItemsList-oj8gN prc-components-UnderlineItemList-xKlKC" role="list"><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a aria-current="page" data-tab-item="code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/github/branch-deploy" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg></span><span data-component="text" data-content="Code">Code</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="issues" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/github/branch-deploy/issues" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg></span><span data-component="text" data-content="Issues">Issues</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">14</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->14<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="pull-requests" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/github/branch-deploy/pulls" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-pull-request" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path></svg></span><span data-component="text" data-content="Pull requests">Pull requests</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">7</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->7<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="actions" data-react-nav="actions-workflows" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/github/branch-deploy/actions" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-play" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path></svg></span><span data-component="text" data-content="Actions">Actions</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="security-and-quality" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/github/branch-deploy/security" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg></span><span data-component="text" data-content="Security and quality">Security and quality</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="insights" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/github/branch-deploy/pulse" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-graph" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg></span><span data-component="text" data-content="Insights">Insights</span></a></li></ul><div class="prc-UnderlineNav-MoreButtonContainer-Dnrq6"><div class="prc-UnderlineNav-MoreButtonDivider-dN0a-"></div><button data-component="overflow-menu-button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk prc-UnderlineNav-MoreButton-Y8soj" data-loading="false" data-size="medium" data-variant="invisible" id="_R_2ktl_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3"><span>More<span class="prc-src-InternalVisuallyHidden-2YaI6"> items</span></span></span></span><span data-component="trailingAction" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></button></div></nav><div class="d-none"></div></header></div>
</react-partial>


  



<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
    <div id="repo-content-pjax-container" class="repository-content " >
    



    
      
    








<react-app
  app-name="code-view"
  initial-path="/github/branch-deploy/blob/main/docs/examples.md"
  style="display: block; min-height: calc(100vh - 64px);"
  data-attempted-ssr="true"
  data-ssr="true"
  data-lazy="false"
  data-alternate="false"
  data-data-router-enabled="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-app.embeddedData">{"payload":{"codeViewBlobRoute":{"csv":null,"csvError":null,"headerInfo":{"toc":[{"level":1,"text":"Examples","anchor":"examples","htmlText":"Examples"},{"level":2,"text":"Table of Contents","anchor":"table-of-contents","htmlText":"Table of Contents"},{"level":2,"text":"Simple Example","anchor":"simple-example","htmlText":"Simple Example"},{"level":2,"text":"Terraform","anchor":"terraform","htmlText":"Terraform"},{"level":2,"text":"Terraform with Trusted Checkouts","anchor":"terraform-with-trusted-checkouts","htmlText":"Terraform with Trusted Checkouts"},{"level":3,"text":".github/workflows/branch-deploy.yml","anchor":"githubworkflowsbranch-deployyml","htmlText":".github/workflows/branch-deploy.yml"},{"level":3,"text":".github/workflows/deploy.yml","anchor":"githubworkflowsdeployyml","htmlText":".github/workflows/deploy.yml"},{"level":3,"text":".github/workflows/unlock-on-merge.yml","anchor":"githubworkflowsunlock-on-mergeyml","htmlText":".github/workflows/unlock-on-merge.yml"},{"level":3,"text":".github/deployment_message.md","anchor":"githubdeployment_messagemd","htmlText":".github/deployment_message.md"},{"level":2,"text":"Heroku","anchor":"heroku","htmlText":"Heroku"},{"level":2,"text":"Railway","anchor":"railway","htmlText":"Railway"},{"level":2,"text":"SSH","anchor":"ssh","htmlText":"SSH"},{"level":2,"text":"Cloudflare Pages","anchor":"cloudflare-pages","htmlText":"Cloudflare Pages"},{"level":2,"text":"Cloudflare Workers","anchor":"cloudflare-workers","htmlText":"Cloudflare Workers"},{"level":2,"text":"Multiple Jobs","anchor":"multiple-jobs","htmlText":"Multiple Jobs"},{"level":2,"text":"Multiple Jobs with GitHub Pages and Hugo","anchor":"multiple-jobs-with-github-pages-and-hugo","htmlText":"Multiple Jobs with GitHub Pages and Hugo"},{"level":2,"text":"Multiple Jobs with GitHub Pages and Astro","anchor":"multiple-jobs-with-github-pages-and-astro","htmlText":"Multiple Jobs with GitHub Pages and Astro"},{"level":2,"text":"Multiple Jobs with GitHub Environments","anchor":"multiple-jobs-with-github-environments","htmlText":"Multiple Jobs with GitHub Environments"}]},"issueTemplate":null,"discussionTemplate":null,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExamples\u003c/h1\u003e\u003ca id=\"user-content-examples\" class=\"anchor\" aria-label=\"Permalink: Examples\" href=\"#examples\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis section contains real world and common examples of how you could use this Action\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eNote: In all examples, we will be using \u003ccode\u003euses: github/branch-deploy@vX.X.X\u003c/code\u003e. Replace \u003ccode\u003eX.X.X\u003c/code\u003e with the \u003ca href=\"https://github.com/marketplace/actions/branch-deploy\"\u003elatest version\u003c/a\u003e of this Action\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTable of Contents\u003c/h2\u003e\u003ca id=\"user-content-table-of-contents\" class=\"anchor\" aria-label=\"Permalink: Table of Contents\" href=\"#table-of-contents\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eQuick links below to jump to a specific branch-deploy example:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#examples\"\u003eExamples\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#table-of-contents\"\u003eTable of Contents\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#simple-example\"\u003eSimple Example\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#terraform\"\u003eTerraform\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#terraform-with-trusted-checkouts\"\u003eTerraform with Trusted Checkouts\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#heroku\"\u003eHeroku\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#railway\"\u003eRailway\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#ssh\"\u003eSSH\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#cloudflare-pages\"\u003eCloudflare Pages\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#cloudflare-workers\"\u003eCloudflare Workers\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#multiple-jobs\"\u003eMultiple Jobs\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#multiple-jobs-with-github-pages-and-hugo\"\u003eMultiple Jobs with GitHub Pages and Hugo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#multiple-jobs-with-github-pages-and-astro\"\u003eMultiple Jobs with GitHub Pages and Astro\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#multiple-jobs-with-github-environments\"\u003eMultiple Jobs with GitHub Environments\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSimple Example\u003c/h2\u003e\u003ca id=\"user-content-simple-example\" class=\"anchor\" aria-label=\"Permalink: Simple Example\" href=\"#simple-example\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis is the simplest possible example of how you could use the branch-deploy Action for reference\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.noop\u003c/code\u003e will run the noop deploy step only (you can configure noop deployments however you like, this is just an example)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e will deploy the current branch via the deploy step only (you can configure deployments however you like, this is just an example)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\n# Permissions needed for reacting and adding comments for IssueOps commands\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  deploy:\n    name: deploy\n    runs-on: ubuntu-latest\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n\n    steps:\n      # The branch-deploy Action\n      - name: branch-deploy\n        id: branch-deploy\n        uses: github/branch-deploy@vX.X.X\n\n        # If the branch-deploy Action was triggered, checkout our branch\n      - uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          persist-credentials: false\n\n        # If the branch-deploy Action was triggered, run the noop deployment (i.e. '.noop')\n      - name: noop deploy\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\n        run: \u0026lt;do-your-noop-deployment\u0026gt; # this could be anything you want\n\n        # If the branch-deploy Action was triggered, run the real deployment (i.e. '.deploy')\n      - name: deploy\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\n        run: \u0026lt;do-your-deployment\u0026gt; # this could be anything you want\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Permissions needed for reacting and adding comments for IssueOps commands\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The branch-deploy Action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, checkout our branch\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, run the noop deployment (i.e. '.noop')\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003enoop deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u0026lt;do-your-noop-deployment\u0026gt; \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this could be anything you want\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, run the real deployment (i.e. '.deploy')\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u0026lt;do-your-deployment\u0026gt; \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this could be anything you want\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTerraform\u003c/h2\u003e\u003ca id=\"user-content-terraform\" class=\"anchor\" aria-label=\"Permalink: Terraform\" href=\"#terraform\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis example shows how you could use this Action with \u003ca href=\"https://www.terraform.io/\" rel=\"nofollow\"\u003eTerraform\u003c/a\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.noop\u003c/code\u003e triggers a Terraform plan\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e triggers a Terraform apply\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eAll deployment results get posted as a comment in the branch deploy output on your pull request\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eA live example can be found \u003ca href=\"https://github.com/the-hideout/cloudflare/blob/3f3adedb729b9aba0cc324a161ad8ddd6f56141b/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\n# The working directory where our Terraform files are located\nenv:\n  WORKING_DIR: terraform/\n\n# Permissions needed for reacting and adding comments for IssueOps commands\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  deploy:\n    name: deploy\n    runs-on: ubuntu-latest\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n    environment: production-secrets # the locked down environment we pull secrets from\n    defaults:\n      run:\n        working-directory: ${{ env.WORKING_DIR }} # the directory we use where all our TF files are stored\n\n    steps:\n      # The branch-deploy Action\n      - name: branch-deploy\n        id: branch-deploy\n        uses: github/branch-deploy@vX.X.X\n\n        # If the branch-deploy Action was triggered, checkout our branch\n      - name: Checkout\n        if: steps.branch-deploy.outputs.continue == 'true'\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          persist-credentials: false\n\n        # Setup Terraform on our Actions runner\n      - uses: hashicorp/setup-terraform@ed3a0531877aca392eb870f440d9ae7aba83a6bd # pin@v1\n        if: steps.branch-deploy.outputs.continue == 'true'\n        with:\n          terraform_version: 1.1.7 # use the version of Terraform your project uses here\n          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}\n\n        # Run Terraform init in our working directory\n      - name: Terraform init\n        if: steps.branch-deploy.outputs.continue == 'true'\n        run: terraform init\n\n        # If '.noop' was used, run a Terraform plan\n      - name: Terraform plan\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\n        id: plan\n        run: terraform plan -no-color\n        continue-on-error: true # continue on error as we will handle errors later on\n\n        # If '.deploy' was used, run a Terraform apply\n      - name: Terraform apply\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\n        id: apply\n        run: terraform apply -no-color -auto-approve\n        continue-on-error: true # continue on error as we will handle errors later on\n\n        # This step writes the TF plan/apply output to $GITHUB_ENV which the branch-deploy Action will read from and post as a comment on the pull request\n      - name: Terraform plan output\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\n        env:\n          TF_STDOUT: ${{ steps.plan.outputs.stdout }}\n        run: |\n          delimiter=\u0026quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\u0026quot;\n          while printf '%s\\n' \u0026quot;$TF_STDOUT\u0026quot; | grep -Fxq \u0026quot;$delimiter\u0026quot;; do\n            delimiter=\u0026quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\u0026quot;\n          done\n          {\n            printf 'DEPLOY_MESSAGE\u0026lt;\u0026lt;%s\\n' \u0026quot;$delimiter\u0026quot;\n            printf '%s\\n' '```terraform'\n            printf '%s\\n' \u0026quot;$TF_STDOUT\u0026quot;\n            printf '%s\\n' '```'\n            printf '%s\\n' \u0026quot;$delimiter\u0026quot;\n          } \u0026gt;\u0026gt; \u0026quot;$GITHUB_ENV\u0026quot;\n\n      - name: Terraform apply output\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\n        env:\n          TF_STDOUT: ${{ steps.apply.outputs.stdout }}\n        run: |\n          delimiter=\u0026quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\u0026quot;\n          while printf '%s\\n' \u0026quot;$TF_STDOUT\u0026quot; | grep -Fxq \u0026quot;$delimiter\u0026quot;; do\n            delimiter=\u0026quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\u0026quot;\n          done\n          {\n            printf 'DEPLOY_MESSAGE\u0026lt;\u0026lt;%s\\n' \u0026quot;$delimiter\u0026quot;\n            printf '%s\\n' '```terraform'\n            printf '%s\\n' \u0026quot;$TF_STDOUT\u0026quot;\n            printf '%s\\n' '```'\n            printf '%s\\n' \u0026quot;$delimiter\u0026quot;\n          } \u0026gt;\u0026gt; \u0026quot;$GITHUB_ENV\u0026quot;\n\n        # Here we handle any errors that might have occurred during the Terraform plan/apply and exit accordingly\n      - name: Check Terraform plan output\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' \u0026amp;\u0026amp; steps.plan.outcome == 'failure' }}\n        run: exit 1\n      - name: Check Terraform apply output\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.apply.outcome == 'failure' }}\n        run: exit 1\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The working directory where our Terraform files are located\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eWORKING_DIR\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform/\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Permissions needed for reacting and adding comments for IssueOps commands\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction-secrets \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the locked down environment we pull secrets from\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003edefaults\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e:\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.WORKING_DIR }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the directory we use where all our TF files are stored\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The branch-deploy Action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, checkout our branch\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCheckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true'\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Setup Terraform on our Actions runner\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ehashicorp/setup-terraform@ed3a0531877aca392eb870f440d9ae7aba83a6bd \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true'\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eterraform_version\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e1.1.7 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e use the version of Terraform your project uses here\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ecli_config_credentials_token\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.TF_API_TOKEN }}\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Run Terraform init in our working directory\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTerraform init\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true'\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform init\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If '.noop' was used, run a Terraform plan\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTerraform plan\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eplan\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform plan -no-color\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003econtinue-on-error\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrue \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e continue on error as we will handle errors later on\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If '.deploy' was used, run a Terraform apply\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTerraform apply\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eapply\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform apply -no-color -auto-approve\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003econtinue-on-error\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrue \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e continue on error as we will handle errors later on\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e This step writes the TF plan/apply output to $GITHUB_ENV which the branch-deploy Action will read from and post as a comment on the pull request\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTerraform plan output\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eTF_STDOUT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.plan.outputs.stdout }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          while printf '%s\\n' \"$TF_STDOUT\" | grep -Fxq \"$delimiter\"; do\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          done\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            printf 'DEPLOY_MESSAGE\u0026lt;\u0026lt;%\u003cspan class=\"pl-s1\"\u003es\\n' \"$delimiter\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' '```terraform'\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' \"$TF_STDOUT\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' '```'\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' \"$delimiter\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          } \u0026gt;\u0026gt; \"$GITHUB_ENV\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e      - name: Terraform apply output\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        env:\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          TF_STDOUT: ${{ steps.apply.outputs.stdout }}\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        run: |\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          while printf '%s\\n' \"$TF_STDOUT\" | grep -Fxq \"$delimiter\"; do\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          done\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf 'DEPLOY_MESSAGE\u0026lt;\u0026lt;%s\\n' \"$delimiter\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' '```terraform'\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' \"$TF_STDOUT\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' '```'\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '%s\\n' \"$delimiter\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          } \u0026gt;\u0026gt; \"$GITHUB_ENV\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        # Here we handle any errors that might have occurred during the Terraform plan/apply and exit accordingly\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e      - name: Check Terraform plan output\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' \u0026amp;\u0026amp; steps.plan.outcome == 'failure' }}\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        run: exit 1\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e      - name: Check Terraform apply output\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.apply.outcome == 'failure' }}\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        run: exit 1\u003c/span\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTerraform with Trusted Checkouts\u003c/h2\u003e\u003ca id=\"user-content-terraform-with-trusted-checkouts\" class=\"anchor\" aria-label=\"Permalink: Terraform with Trusted Checkouts\" href=\"#terraform-with-trusted-checkouts\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis example shows a hardened Terraform setup that separates trusted deployment\nhelper code from the working pull request code selected by branch-deploy.\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.noop\u003c/code\u003e runs \u003ccode\u003eterraform plan\u003c/code\u003e from the exact working commit SHA selected by branch-deploy\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e runs \u003ccode\u003eterraform apply\u003c/code\u003e from that same working commit SHA\u003c/li\u003e\n\u003cli\u003ethe deployment message template is fetched by Branch Deploy at the exact trusted workflow SHA\u003c/li\u003e\n\u003cli\u003eTerraform output is captured in \u003ccode\u003eRUNNER_TEMP\u003c/code\u003e and exported through \u003ccode\u003eDEPLOY_MESSAGE\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003emerge deploy mode avoids redeploying a default-branch commit only when the newest relevant Branch Deploy deployment is active and has the same commit tree\u003c/li\u003e\n\u003cli\u003eunlock-on-merge mode cleans up sticky locks after the pull request merges\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eFor the general security model behind this pattern, see the\n\u003ca href=\"/github/branch-deploy/blob/main/docs/trusted-checkouts.md\"\u003etrusted checkout hardening guide\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\u003ccode\u003e.github/workflows/branch-deploy.yml\u003c/code\u003e\u003c/h3\u003e\u003ca id=\"user-content-githubworkflowsbranch-deployyml\" class=\"anchor\" aria-label=\"Permalink: .github/workflows/branch-deploy.yml\" href=\"#githubworkflowsbranch-deployyml\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\nenv:\n  TF_IN_AUTOMATION: \u0026quot;true\u0026quot;\n\njobs:\n  branch-deploy:\n    if:\n      ${{ github.event.issue.pull_request \u0026amp;\u0026amp;\n      (startsWith(github.event.comment.body, '.deploy') ||\n      startsWith(github.event.comment.body, '.noop') ||\n      startsWith(github.event.comment.body, '.lock') ||\n      startsWith(github.event.comment.body, '.help') ||\n      startsWith(github.event.comment.body, '.wcid') ||\n      startsWith(github.event.comment.body, '.unlock')) }}\n    runs-on: ubuntu-latest\n    environment:\n      name: production\n      deployment: false\n    concurrency:\n      group: ${{ (startsWith(github.event.comment.body, '.deploy') || startsWith(github.event.comment.body, '.noop')) \u0026amp;\u0026amp; 'terraform-production' || format('branch-deploy-support-{0}', github.run_id) }}\n      cancel-in-progress: false\n      queue: max\n\n    steps:\n      - name: branch-deploy\n        id: branch-deploy\n        uses: github/branch-deploy@vX.X.X\n        with:\n          trigger: \u0026quot;.deploy\u0026quot;\n          sticky_locks: true\n          deployment_confirmation: true\n          deploy_message_path: .github/deployment_message.md\n          allow_forks: false\n\n      - name: derive working checkout path\n        id: working-path\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          DEPLOY_SHA: ${{ steps.branch-deploy.outputs.sha }}\n        run: |\n          set -euo pipefail\n          echo \u0026quot;DEPLOY_SHA=${DEPLOY_SHA}\u0026quot;\n\n          if [[ ! \u0026quot;${DEPLOY_SHA}\u0026quot; =~ ^[0-9a-fA-F]{40}([0-9a-fA-F]{24})?$ ]]; then\n            echo \u0026quot;invalid branch-deploy sha output: ${DEPLOY_SHA}\u0026quot; \u0026gt;\u0026amp;2\n            exit 1\n          fi\n\n          working_dir=\u0026quot;deployment-${DEPLOY_SHA}\u0026quot;\n\n          echo \u0026quot;working_dir=${working_dir}\u0026quot; \u0026gt;\u0026gt; \u0026quot;${GITHUB_OUTPUT}\u0026quot;\n          echo \u0026quot;working checkout directory: ${working_dir}\u0026quot;\n\n      - name: checkout working deployment sha\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          path: ${{ steps.working-path.outputs.working_dir }}\n          fetch-depth: 1\n          persist-credentials: false\n\n      - name: verify checkout provenance\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          WORKING_DIR: ${{ steps.working-path.outputs.working_dir }}\n          WORKING_SHA: ${{ steps.branch-deploy.outputs.sha }}\n        run: |\n          set -euo pipefail\n\n          working_head=\u0026quot;$(git -C \u0026quot;${WORKING_DIR}\u0026quot; rev-parse HEAD)\u0026quot;\n\n          if [[ \u0026quot;${working_head}\u0026quot; != \u0026quot;${WORKING_SHA}\u0026quot; ]]; then\n            echo \u0026quot;working checkout HEAD mismatch: expected ${WORKING_SHA}, got ${working_head}\u0026quot; \u0026gt;\u0026amp;2\n            exit 1\n          fi\n\n          echo \u0026quot;working checkout: ${WORKING_DIR}@${working_head}\u0026quot;\n\n      - name: prepare terraform output path\n        id: terraform-output\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        run: |\n          set -euo pipefail\n\n          output_dir=\u0026quot;$(mktemp -d \u0026quot;${RUNNER_TEMP}/branch-deploy-output.XXXXXX\u0026quot;)\u0026quot;\n          output_path=\u0026quot;${output_dir}/terraform-output.txt\u0026quot;\n          : \u0026gt; \u0026quot;${output_path}\u0026quot;\n\n          if [[ -L \u0026quot;${output_path}\u0026quot; || ! -f \u0026quot;${output_path}\u0026quot; ]]; then\n            echo \u0026quot;terraform output path is not a regular file: ${output_path}\u0026quot; \u0026gt;\u0026amp;2\n            exit 1\n          fi\n\n          echo \u0026quot;path=${output_path}\u0026quot; \u0026gt;\u0026gt; \u0026quot;${GITHUB_OUTPUT}\u0026quot;\n          echo \u0026quot;terraform output path: ${output_path}\u0026quot;\n\n      - name: read terraform version\n        id: terraform-version\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform\n        run: echo \u0026quot;version=$(cat .terraform-version)\u0026quot; \u0026gt;\u0026gt; \u0026quot;$GITHUB_OUTPUT\u0026quot;\n\n      - name: setup terraform\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        uses: hashicorp/setup-terraform@v4\n        with:\n          terraform_version: ${{ steps.terraform-version.outputs.version }}\n\n      - name: terraform init\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform\n        env:\n          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}\n        run: terraform init\n\n      - name: terraform plan\n        id: plan\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\n        continue-on-error: true\n        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform\n        env:\n          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}\n          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}\n        run: |\n          set -o pipefail\n          terraform plan -no-color -compact-warnings | tee \u0026quot;$TERRAFORM_OUTPUT_PATH\u0026quot;\n\n      - name: terraform apply\n        id: apply\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\n        continue-on-error: true\n        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform\n        env:\n          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}\n          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}\n        run: |\n          set -o pipefail\n          terraform apply -auto-approve -no-color -compact-warnings | tee \u0026quot;$TERRAFORM_OUTPUT_PATH\u0026quot;\n\n      - name: verify terraform output capture\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}\n        run: |\n          set -euo pipefail\n\n          if [[ -L \u0026quot;${TERRAFORM_OUTPUT_PATH}\u0026quot; || ! -f \u0026quot;${TERRAFORM_OUTPUT_PATH}\u0026quot; ]]; then\n            echo \u0026quot;terraform output path is not a regular file: ${TERRAFORM_OUTPUT_PATH}\u0026quot; \u0026gt;\u0026amp;2\n            exit 1\n          fi\n\n      - name: export deploy message\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          RESULTS_PATH: ${{ steps.terraform-output.outputs.path }}\n        run: |\n          set -euo pipefail\n          delimiter=\u0026quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\u0026quot;\n          while grep -Fxq \u0026quot;${delimiter}\u0026quot; \u0026quot;${RESULTS_PATH}\u0026quot;; do\n            delimiter=\u0026quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\u0026quot;\n          done\n          {\n            printf 'DEPLOY_MESSAGE\u0026lt;\u0026lt;%s\\n' \u0026quot;${delimiter}\u0026quot;\n            cat \u0026quot;${RESULTS_PATH}\u0026quot;\n            printf '\\n%s\\n' \u0026quot;${delimiter}\u0026quot;\n          } \u0026gt;\u0026gt; \u0026quot;${GITHUB_ENV}\u0026quot;\n\n      - name: check terraform plan\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' \u0026amp;\u0026amp; steps.plan.outcome == 'failure' }}\n        run: exit 1\n\n      - name: check terraform apply\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.apply.outcome == 'failure' }}\n        run: exit 1\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eTF_IN_AUTOMATION\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003etrue\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003ebranch-deploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e:\n      \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request \u0026amp;\u0026amp;\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e(startsWith(github.event.comment.body, '.deploy') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003estartsWith(github.event.comment.body, '.noop') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003estartsWith(github.event.comment.body, '.lock') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003estartsWith(github.event.comment.body, '.help') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003estartsWith(github.event.comment.body, '.wcid') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003estartsWith(github.event.comment.body, '.unlock')) }}\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003edeployment\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003econcurrency\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003egroup\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ (startsWith(github.event.comment.body, '.deploy') || startsWith(github.event.comment.body, '.noop')) \u0026amp;\u0026amp; 'terraform-production' || format('branch-deploy-support-{0}', github.run_id) }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003ecancel-in-progress\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003equeue\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003emax\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003etrigger\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e.deploy\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003esticky_locks\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003edeployment_confirmation\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003edeploy_message_path\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e.github/deployment_message.md\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eallow_forks\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ederive working checkout path\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eworking-path\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eDEPLOY_SHA\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          set -euo pipefail\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"DEPLOY_SHA=${DEPLOY_SHA}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [[ ! \"${DEPLOY_SHA}\" =~ ^[0-9a-fA-F]{40}([0-9a-fA-F]{24})?$ ]]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"invalid branch-deploy sha output: ${DEPLOY_SHA}\" \u0026gt;\u0026amp;2\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 1\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          working_dir=\"deployment-${DEPLOY_SHA}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"working_dir=${working_dir}\" \u0026gt;\u0026gt; \"${GITHUB_OUTPUT}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"working checkout directory: ${working_dir}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003echeckout working deployment sha\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epath\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.working-path.outputs.working_dir }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003efetch-depth\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003everify checkout provenance\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eWORKING_DIR\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.working-path.outputs.working_dir }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eWORKING_SHA\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          set -euo pipefail\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          working_head=\"$(git -C \"${WORKING_DIR}\" rev-parse HEAD)\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [[ \"${working_head}\" != \"${WORKING_SHA}\" ]]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"working checkout HEAD mismatch: expected ${WORKING_SHA}, got ${working_head}\" \u0026gt;\u0026amp;2\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 1\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"working checkout: ${WORKING_DIR}@${working_head}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eprepare terraform output path\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform-output\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          set -euo pipefail\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          output_dir=\"$(mktemp -d \"${RUNNER_TEMP}/branch-deploy-output.XXXXXX\")\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          output_path=\"${output_dir}/terraform-output.txt\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          : \u0026gt; \"${output_path}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [[ -L \"${output_path}\" || ! -f \"${output_path}\" ]]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"terraform output path is not a regular file: ${output_path}\" \u0026gt;\u0026amp;2\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 1\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"path=${output_path}\" \u0026gt;\u0026gt; \"${GITHUB_OUTPUT}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"terraform output path: ${output_path}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread terraform version\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform-version\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.working-path.outputs.working_dir }}/terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eecho \"version=$(cat .terraform-version)\" \u0026gt;\u0026gt; \"$GITHUB_OUTPUT\"\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esetup terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ehashicorp/setup-terraform@v4\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eterraform_version\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.terraform-version.outputs.version }}\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform init\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.working-path.outputs.working_dir }}/terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eTF_TOKEN_app_terraform_io\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.TF_API_TOKEN }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform init\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform plan\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eplan\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003econtinue-on-error\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.working-path.outputs.working_dir }}/terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eTF_TOKEN_app_terraform_io\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.TF_API_TOKEN }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eTERRAFORM_OUTPUT_PATH\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.terraform-output.outputs.path }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          set -o pipefail\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          terraform plan -no-color -compact-warnings | tee \"$TERRAFORM_OUTPUT_PATH\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform apply\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eapply\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003econtinue-on-error\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.working-path.outputs.working_dir }}/terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eTF_TOKEN_app_terraform_io\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.TF_API_TOKEN }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eTERRAFORM_OUTPUT_PATH\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.terraform-output.outputs.path }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          set -o pipefail\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          terraform apply -auto-approve -no-color -compact-warnings | tee \"$TERRAFORM_OUTPUT_PATH\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003everify terraform output capture\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eTERRAFORM_OUTPUT_PATH\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.terraform-output.outputs.path }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          set -euo pipefail\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [[ -L \"${TERRAFORM_OUTPUT_PATH}\" || ! -f \"${TERRAFORM_OUTPUT_PATH}\" ]]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"terraform output path is not a regular file: ${TERRAFORM_OUTPUT_PATH}\" \u0026gt;\u0026amp;2\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 1\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eexport deploy message\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eRESULTS_PATH\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.terraform-output.outputs.path }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          set -euo pipefail\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          while grep -Fxq \"${delimiter}\" \"${RESULTS_PATH}\"; do\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          done\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            printf 'DEPLOY_MESSAGE\u0026lt;\u0026lt;%\u003cspan class=\"pl-s1\"\u003es\\n' \"${delimiter}\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            cat \"${RESULTS_PATH}\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e            printf '\\n%s\\n' \"${delimiter}\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e          } \u0026gt;\u0026gt; \"${GITHUB_ENV}\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e      - name: check terraform plan\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop == 'true' \u0026amp;\u0026amp; steps.plan.outcome == 'failure' }}\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        run: exit 1\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e      - name: check terraform apply\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.apply.outcome == 'failure' }}\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-s1\"\u003e        run: exit 1\u003c/span\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\u003ccode\u003e.github/workflows/deploy.yml\u003c/code\u003e\u003c/h3\u003e\u003ca id=\"user-content-githubworkflowsdeployyml\" class=\"anchor\" aria-label=\"Permalink: .github/workflows/deploy.yml\" href=\"#githubworkflowsdeployyml\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: deploy\n\non:\n  push:\n    branches: [\u0026quot;main\u0026quot;]\n\npermissions:\n  contents: read\n  deployments: write\n\njobs:\n  deployment-check:\n    runs-on: ubuntu-latest\n    outputs:\n      continue: ${{ steps.deployment-check.outputs.continue }}\n      sha: ${{ steps.deployment-check.outputs.sha }}\n\n    steps:\n      - name: deployment check\n        id: deployment-check\n        uses: github/branch-deploy@vX.X.X\n        with:\n          merge_deploy_mode: true\n          environment: production\n\n  deploy:\n    if: ${{ needs.deployment-check.outputs.continue == 'true' }}\n    needs: deployment-check\n    runs-on: ubuntu-latest\n    concurrency:\n      group: terraform-production\n      cancel-in-progress: false\n      queue: max\n    environment: production\n    defaults:\n      run:\n        working-directory: terraform/\n    env:\n      TF_IN_AUTOMATION: \u0026quot;true\u0026quot;\n\n    steps:\n      - name: checkout\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ needs.deployment-check.outputs.sha }}\n          fetch-depth: 1\n          persist-credentials: false\n\n      - name: read terraform version\n        id: terraform-version\n        working-directory: .\n        run: echo \u0026quot;version=$(cat terraform/.terraform-version)\u0026quot; \u0026gt;\u0026gt; \u0026quot;$GITHUB_OUTPUT\u0026quot;\n\n      - name: setup terraform\n        uses: hashicorp/setup-terraform@v4\n        with:\n          terraform_version: ${{ steps.terraform-version.outputs.version }}\n\n      - name: terraform init\n        env:\n          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}\n        run: terraform init\n\n      - name: terraform apply\n        env:\n          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}\n        run: terraform apply -auto-approve -no-color -compact-warnings\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epush\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003ebranches\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[\"main\"]\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeployment-check\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eoutputs\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003econtinue\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deployment-check.outputs.continue }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003esha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deployment-check.outputs.sha }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeployment check\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeployment-check\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003emerge_deploy_mode\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction\u003c/span\u003e\n\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.deployment-check.outputs.continue == 'true' }}\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeployment-check\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003econcurrency\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003egroup\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform-production\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003ecancel-in-progress\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003equeue\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003emax\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003edefaults\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e:\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform/\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003eTF_IN_AUTOMATION\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003etrue\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003echeckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.deployment-check.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003efetch-depth\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread terraform version\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform-version\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e.\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eecho \"version=$(cat terraform/.terraform-version)\" \u0026gt;\u0026gt; \"$GITHUB_OUTPUT\"\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esetup terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ehashicorp/setup-terraform@v4\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eterraform_version\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.terraform-version.outputs.version }}\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform init\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eTF_TOKEN_app_terraform_io\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.TF_API_TOKEN }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform init\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform apply\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eTF_TOKEN_app_terraform_io\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.TF_API_TOKEN }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform apply -auto-approve -no-color -compact-warnings\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\u003ccode\u003e.github/workflows/unlock-on-merge.yml\u003c/code\u003e\u003c/h3\u003e\u003ca id=\"user-content-githubworkflowsunlock-on-mergeyml\" class=\"anchor\" aria-label=\"Permalink: .github/workflows/unlock-on-merge.yml\" href=\"#githubworkflowsunlock-on-mergeyml\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: Unlock On Merge\n\non:\n  pull_request:\n    types: [closed]\n\npermissions:\n  contents: write\n\njobs:\n  unlock-on-merge:\n    runs-on: ubuntu-latest\n    if: github.event.pull_request.merged == true\n\n    steps:\n      - name: unlock on merge\n        id: unlock-on-merge\n        uses: github/branch-deploy@vX.X.X\n        with:\n          unlock_on_merge_mode: true\n          environment_targets: production\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eUnlock On Merge\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull_request\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[closed]\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eunlock-on-merge\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub.event.pull_request.merged == true\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eunlock on merge\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eunlock-on-merge\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eunlock_on_merge_mode\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eenvironment_targets\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\u003ccode\u003e.github/deployment_message.md\u003c/code\u003e\u003c/h3\u003e\u003ca id=\"user-content-githubdeployment_messagemd\" class=\"anchor\" aria-label=\"Permalink: .github/deployment_message.md\" href=\"#githubdeployment_messagemd\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-md notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"### Deployment Results {{ \u0026quot;:white_check_mark:\u0026quot; if status === \u0026quot;success\u0026quot; else \u0026quot;:x:\u0026quot; }}\n\n{% if status === \u0026quot;success\u0026quot; %}**{{ actor }}** successfully **{{ \u0026quot;noop\u0026quot; if noop else \u0026quot;branch\u0026quot; }}** deployed branch `{{ ref }}` to **{{ environment }}**{% endif %}{% if status === \u0026quot;failure\u0026quot; %}**{{ actor }}** your **{{ \u0026quot;noop\u0026quot; if noop else \u0026quot;branch\u0026quot; }}** deployment of `{{ ref }}` failed to deploy to the **{{ environment }}** environment{% endif %}\n\n\u0026lt;details\u0026gt;\u0026lt;summary\u0026gt;Show Results\u0026lt;/summary\u0026gt;\n\n```terraform\n{{ results }}\n```\n\n\u0026lt;/details\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-mh\"\u003e### \u003cspan class=\"pl-en\"\u003eDeployment Results {{ \"\u003cspan class=\"pl-s\"\u003e:\u003cspan class=\"pl-k\"\u003ewhite_check_mark\u003c/span\u003e:\u003c/span\u003e\" if status === \"success\" else \"\u003cspan class=\"pl-s\"\u003e:\u003cspan class=\"pl-k\"\u003ex\u003c/span\u003e:\u003c/span\u003e\" }}\u003c/span\u003e\u003c/span\u003e\n\n{% if status === \"success\" %}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e{{ actor }}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e successfully \u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e{{ \"noop\" if noop else \"branch\" }}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e deployed branch \u003cspan class=\"pl-s\"\u003e`\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e{{ ref }}\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e`\u003c/span\u003e to \u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e{{ environment }}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e{% endif %}{% if status === \"failure\" %}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e{{ actor }}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e your \u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e{{ \"noop\" if noop else \"branch\" }}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e deployment of \u003cspan class=\"pl-s\"\u003e`\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e{{ ref }}\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e`\u003c/span\u003e failed to deploy to the \u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e{{ environment }}\u003cspan class=\"pl-s\"\u003e**\u003c/span\u003e environment{% endif %}\n\n\u0026lt;\u003cspan class=\"pl-ent\"\u003edetails\u003c/span\u003e\u0026gt;\u0026lt;\u003cspan class=\"pl-ent\"\u003esummary\u003c/span\u003e\u0026gt;Show Results\u0026lt;/\u003cspan class=\"pl-ent\"\u003esummary\u003c/span\u003e\u0026gt;\n\n\u003cspan class=\"pl-s\"\u003e```\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eterraform\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e{{ results }}\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003e\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e```\u003c/span\u003e\n\n\u0026lt;/\u003cspan class=\"pl-ent\"\u003edetails\u003c/span\u003e\u0026gt;\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eHeroku\u003c/h2\u003e\u003ca id=\"user-content-heroku\" class=\"anchor\" aria-label=\"Permalink: Heroku\" href=\"#heroku\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis example shows how you could use this Action with \u003ca href=\"https://heroku.com\" rel=\"nofollow\"\u003eHeroku\u003c/a\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.noop\u003c/code\u003e has no effect here (but you could change that)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e takes your current branch and deploys it to Heroku\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eA live example can be found \u003ca href=\"https://github.com/the-hideout/stash/blob/aef5a5f16b4fa6946d2eba107e7b92c5f6583c0d/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  deploy:\n    name: deploy\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n    runs-on: ubuntu-latest\n    environment: production-secrets # the locked down environment we pull secrets from\n\n    steps:\n      # The branch-deploy Action\n      - name: branch-deploy\n        id: branch-deploy\n        uses: github/branch-deploy@vX.X.X\n\n        # If the branch-deploy Action was triggered, checkout our branch\n      - name: Checkout\n        if: steps.branch-deploy.outputs.continue == 'true'\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          persist-credentials: false\n\n        # Deploy our branch to Heroku\n      - name: Deploy to Heroku\n        if: steps.branch-deploy.outputs.continue == 'true'\n        uses: AkhileshNS/heroku-deploy@79ef2ae4ff9b897010907016b268fd0f88561820 # pin@v3.12.12\n        with:\n          heroku_app_name: \u0026lt;your-heroku-app-name-here\u0026gt;\n          heroku_email: ${{ secrets.HEROKU_EMAIL }}\n          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction-secrets \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the locked down environment we pull secrets from\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The branch-deploy Action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, checkout our branch\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCheckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true'\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Deploy our branch to Heroku\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eDeploy to Heroku\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true'\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eAkhileshNS/heroku-deploy@79ef2ae4ff9b897010907016b268fd0f88561820 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v3.12.12\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eheroku_app_name\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u0026lt;your-heroku-app-name-here\u0026gt;\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eheroku_email\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.HEROKU_EMAIL }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eheroku_api_key\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.HEROKU_API_KEY }}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRailway\u003c/h2\u003e\u003ca id=\"user-content-railway\" class=\"anchor\" aria-label=\"Permalink: Railway\" href=\"#railway\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis example shows how you could use this Action with \u003ca href=\"https://railway.app\" rel=\"nofollow\"\u003eRailway\u003c/a\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.noop\u003c/code\u003e has no effect here (but you could change that)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e takes your current branch and deploys it to Railway\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eA live example can be found \u003ca href=\"https://github.com/the-hideout/stash/blob/ee8af01919f368f35dede3c93f703fd239dbac3c/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e that has some slight modifications to the example below\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  deploy:\n    name: deploy\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n    runs-on: ubuntu-latest\n    environment: production-secrets # the locked down environment we pull secrets from\n\n    steps:\n      # The branch-deploy Action\n      - name: branch-deploy\n        id: branch-deploy\n        uses: github/branch-deploy@vX.X.X\n\n        # If the branch-deploy Action was triggered, checkout our branch\n      - name: Checkout\n        if: steps.branch-deploy.outputs.continue == 'true'\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          persist-credentials: false\n\n        # Install the Railway CLI through npm\n      - name: Install Railway\n        run: npm i -g @railway/cli\n\n        # Deploy our branch to Railway\n      - name: Deploy to Railway\n        if: steps.branch-deploy.outputs.continue == 'true'\n        env:\n          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}\n        run: railway up\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction-secrets \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the locked down environment we pull secrets from\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The branch-deploy Action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, checkout our branch\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCheckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true'\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Install the Railway CLI through npm\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eInstall Railway\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003enpm i -g @railway/cli\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Deploy our branch to Railway\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eDeploy to Railway\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true'\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eRAILWAY_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.RAILWAY_TOKEN }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003erailway up\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSSH\u003c/h2\u003e\u003ca id=\"user-content-ssh\" class=\"anchor\" aria-label=\"Permalink: SSH\" href=\"#ssh\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis example shows how you could use this Action with SSH\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou can define any commands you want to be run in your SSH Action and they would be gated by the branch-deploy Action.\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.noop\u003c/code\u003e has no effect here (but you could change that)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e runs the SSH action with your branch\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eA live example can be found \u003ca href=\"https://github.com/the-hideout/cache/blob/6ee6ee2a69104f165c9f20df6e4e5cbb337b7c54/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\n# Permissions needed for reacting and adding comments for IssueOps commands\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  deploy:\n    environment: production-secrets # the locked down environment we pull secrets from\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n    runs-on: ubuntu-latest\n\n    steps:\n      # The branch-deploy Action\n      - uses: github/branch-deploy@vX.X.X\n        id: branch-deploy\n\n        # If the branch-deploy Action was triggered, checkout our branch\n      - name: Checkout\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          persist-credentials: false\n\n        # Deploy our branch via SSH remote commands\n      - name: SSH Remote Deploy\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\n        uses: appleboy/ssh-action@4a03da89e5c43da56e502053be4bbcb293411883 # pin@v0.1.6\n        with:\n          host: ${{ secrets.SSH_HOST }}\n          username: ${{ secrets.SSH_USERNAME }}\n          key: ${{ secrets.SSH_KEY }}\n          port: ${{ secrets.SSH_PORT }}\n          script_stop: true\n          script: \u0026lt;run-some-ssh-commands-here\u0026gt; # this could be whatever you want\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Permissions needed for reacting and adding comments for IssueOps commands\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eproduction-secrets \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the locked down environment we pull secrets from\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The branch-deploy Action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, checkout our branch\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCheckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Deploy our branch via SSH remote commands\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eSSH Remote Deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eappleboy/ssh-action@4a03da89e5c43da56e502053be4bbcb293411883 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v0.1.6\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ehost\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.SSH_HOST }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eusername\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.SSH_USERNAME }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ekey\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.SSH_KEY }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eport\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.SSH_PORT }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003escript_stop\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003escript\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u0026lt;run-some-ssh-commands-here\u0026gt; \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this could be whatever you want\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCloudflare Pages\u003c/h2\u003e\u003ca id=\"user-content-cloudflare-pages\" class=\"anchor\" aria-label=\"Permalink: Cloudflare Pages\" href=\"#cloudflare-pages\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis example shows how you could use this Action with \u003ca href=\"https://pages.cloudflare.com/\" rel=\"nofollow\"\u003eCloudflare Pages\u003c/a\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.deploy to development\u003c/code\u003e deploys your branch to the development environment\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e deploys your branch to the production environment\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eA live example can be found \u003ca href=\"https://github.com/the-hideout/tarkov-dev/blob/b4417dfeb903985b83a24096b2e1ba2a22f39ddd/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\n# Permissions needed for reacting and adding comments for IssueOps commands\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  deploy:\n    environment: secrets # the locked down environment we pull secrets from\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n    runs-on: ubuntu-latest\n\n    steps:\n      # The branch-deploy Action\n      - uses: github/branch-deploy@vX.X.X\n        id: branch-deploy\n\n        # If the branch-deploy Action was triggered, checkout our branch\n      - name: Checkout\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          persist-credentials: false\n\n        # setup node\n      - uses: actions/setup-node@v4\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        with:\n          node-version: '18'\n          cache: 'npm'\n\n        # Install the npm dependencies to build our cloudflare pages site\n      - name: Install\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        run: npm ci\n\n        # Build our cloudflare pages site\n      - name: Build\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        run: npm run build\n\n        # If '.deploy to development' was used, branch deploy to the development environment\n      - name: deploy - dev\n        id: dev-deploy\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.environment == 'development' }}\n        uses: cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 # pin@3.3.1\n        with:\n          wranglerVersion: '2.13.0' # this can be any version of wrangler you want\n          apiToken: ${{ secrets.CF_API_TOKEN }}\n          accountId: ${{ secrets.CF_ACCOUNT_ID }}\n          command: pages publish build/ --project-name=\u0026lt;your-cloudflare-project-name\u0026gt; --branch=preview\n\n        # If '.deploy' was used, branch deploy to the production environment\n      - name: deploy - prod\n        id: prod-deploy\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.environment == 'production' }}\n        uses: cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 # pin@3.3.1\n        with:\n          wranglerVersion: '2.13.0' # this can be any version of wrangler you want\n          apiToken: ${{ secrets.CF_API_TOKEN }}\n          accountId: ${{ secrets.CF_ACCOUNT_ID }}\n          command: pages publish build/ --project-name=\u0026lt;your-cloudflare-project-name\u0026gt; --branch=main\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Permissions needed for reacting and adding comments for IssueOps commands\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esecrets \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the locked down environment we pull secrets from\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The branch-deploy Action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, checkout our branch\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCheckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e setup node\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/setup-node@v4\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003enode-version\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e18\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ecache\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003enpm\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Install the npm dependencies to build our cloudflare pages site\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eInstall\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003enpm ci\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Build our cloudflare pages site\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eBuild\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003enpm run build\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If '.deploy to development' was used, branch deploy to the development environment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy - dev\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edev-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.environment == 'development' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@3.3.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ewranglerVersion\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e2.13.0\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this can be any version of wrangler you want\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eapiToken\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.CF_API_TOKEN }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eaccountId\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.CF_ACCOUNT_ID }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ecommand\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epages publish build/ --project-name=\u0026lt;your-cloudflare-project-name\u0026gt; --branch=preview\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If '.deploy' was used, branch deploy to the production environment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy - prod\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eprod-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp; steps.branch-deploy.outputs.environment == 'production' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@3.3.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ewranglerVersion\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e2.13.0\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this can be any version of wrangler you want\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eapiToken\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.CF_API_TOKEN }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eaccountId\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.CF_ACCOUNT_ID }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ecommand\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epages publish build/ --project-name=\u0026lt;your-cloudflare-project-name\u0026gt; --branch=main\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCloudflare Workers\u003c/h2\u003e\u003ca id=\"user-content-cloudflare-workers\" class=\"anchor\" aria-label=\"Permalink: Cloudflare Workers\" href=\"#cloudflare-workers\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis example shows how you could use this Action with \u003ca href=\"https://workers.cloudflare.com/\" rel=\"nofollow\"\u003eCloudflare Workers\u003c/a\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e.deploy to development\u003c/code\u003e deploys your branch to the development environment (if you have one with your Cloudflare workers)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.deploy\u003c/code\u003e deploys your branch to the production environment\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eA live example can be found \u003ca href=\"https://github.com/the-hideout/tarkov-api/blob/1677543951d5f2a848c2650eb3400178b8f9a55b/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch-deploy\n\non:\n  issue_comment:\n    types: [created]\n\n# Permissions needed for reacting and adding comments for IssueOps commands\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  deploy:\n    environment: secrets # the locked down environment we pull secrets from\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n    runs-on: ubuntu-latest\n\n    steps:\n      # The branch-deploy Action\n      - uses: github/branch-deploy@vX.X.X\n        id: branch-deploy\n\n        # If the branch-deploy Action was triggered, checkout our branch\n      - name: Checkout\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ steps.branch-deploy.outputs.sha }}\n          persist-credentials: false\n\n        # Install the npm dependencies for your cloudflare workers project\n        # Most importantly, we need to install @cloudflare/wrangler\n      - name: Install dependencies\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        run: npm ci\n\n        # If '.deploy to development' was used, branch deploy to the development environment\n      - name: Publish - Development\n        if: ${{ steps.branch-deploy.outputs.environment == 'development' \u0026amp;\u0026amp;\n          steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp;\n          steps.branch-deploy.outputs.continue == 'true' }}\n        uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # pin@2.0.0\n        with:\n          wranglerVersion: '2.17.0' # this can be any version of wrangler you want\n          apiToken: ${{ secrets.CF_API_TOKEN }}\n          environment: 'development' # here we use development\n\n        # If '.deploy' was used, branch deploy to the production environment\n      - name: Publish - Production\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp;\n          steps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp;\n          steps.branch-deploy.outputs.environment == 'production' }}\n        uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # pin@2.0.0\n        with:\n          wranglerVersion: '2.17.0' # this can be any version of wrangler you want\n          apiToken: ${{ secrets.CF_API_TOKEN }}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Permissions needed for reacting and adding comments for IssueOps commands\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esecrets \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the locked down environment we pull secrets from\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The branch-deploy Action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the branch-deploy Action was triggered, checkout our branch\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCheckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Install the npm dependencies for your cloudflare workers project\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Most importantly, we need to install @cloudflare/wrangler\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eInstall dependencies\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003enpm ci\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If '.deploy to development' was used, branch deploy to the development environment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ePublish - Development\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment == 'development' \u0026amp;\u0026amp;\u003c/span\u003e\n          \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp;\u003c/span\u003e\n          \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@2.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ewranglerVersion\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e2.17.0\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this can be any version of wrangler you want\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eapiToken\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.CF_API_TOKEN }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003edevelopment\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e here we use development\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If '.deploy' was used, branch deploy to the production environment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ePublish - Production\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' \u0026amp;\u0026amp;\u003c/span\u003e\n          \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.noop != 'true' \u0026amp;\u0026amp;\u003c/span\u003e\n          \u003cspan class=\"pl-s\"\u003esteps.branch-deploy.outputs.environment == 'production' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@2.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ewranglerVersion\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e2.17.0\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this can be any version of wrangler you want\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eapiToken\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.CF_API_TOKEN }}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMultiple Jobs\u003c/h2\u003e\u003ca id=\"user-content-multiple-jobs\" class=\"anchor\" aria-label=\"Permalink: Multiple Jobs\" href=\"#multiple-jobs\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you need a complex deployment workflow, you can complete the deployment manually in a separate job. With \u003ccode\u003eskip_completing: true\u003c/code\u003e, your workflow owns final deployment statuses, comments, reactions, labels, and non-sticky lock cleanup. See \u003ca href=\"https://github.com/github/branch-deploy/blob/main/README.md#manual-deployment-control\"\u003ehere\u003c/a\u003e for more details.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eThis is a more advanced example\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: deploy\n\non:\n  issue_comment:\n    types: [created]\n\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\njobs:\n  trigger:\n    if: ${{ github.event.issue.pull_request }} # only run on pull request comments\n    runs-on: ubuntu-latest\n    outputs:\n      continue: ${{ steps.branch-deploy.outputs.continue }}\n      noop: ${{ steps.branch-deploy.outputs.noop }}\n      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}\n      environment: ${{ steps.branch-deploy.outputs.environment }}\n      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}\n      sha: ${{ steps.branch-deploy.outputs.sha }}\n      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}\n      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}\n      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}\n\n    steps:\n      - uses: github/branch-deploy@vX.X.X\n        id: branch-deploy\n        with:\n          trigger: \u0026quot;.deploy\u0026quot;\n          skip_completing: true # we will complete the deployment manually\n\n      - name: Capture deployment lock\n        id: capture-lock\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n        run: |\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          if lock_ref_sha=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}\u0026quot; --jq '.object.sha' 2\u0026gt;/dev/null)\u0026quot;; then\n            printf 'sha=%s\\n' \u0026quot;$lock_ref_sha\u0026quot; \u0026gt;\u0026gt; \u0026quot;$GITHUB_OUTPUT\u0026quot;\n          else\n            echo \u0026quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\u0026quot;\n          fi\n\n  deploy:\n    needs: trigger\n    if: ${{ needs.trigger.outputs.continue == 'true' \u0026amp;\u0026amp; needs.trigger.outputs.noop != 'true' }}\n    runs-on: ubuntu-latest\n\n    steps:\n      # checkout the project's repository based on the commit SHA provided by the branch-deploy step\n      - name: checkout\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ needs.trigger.outputs.sha }}\n          persist-credentials: false\n\n      # You will do your own deployment here\n      - name: fake regular deploy\n        run: echo \u0026quot;I am doing a fake regular deploy\u0026quot;\n\n  # update the deployment result - manually complete the deployment that was created by the branch-deploy action\n  result:\n    needs: [trigger, deploy]\n    runs-on: ubuntu-latest\n    # run even on failures but only if the trigger job set continue to true\n    if: ${{ always() \u0026amp;\u0026amp; needs.trigger.outputs.continue == 'true' }}\n\n    steps:\n      # if a previous step failed, set a variable to use as the deployment status\n      - name: set deployment status\n        id: deploy-status\n        if: ${{ needs.trigger.result == 'failure' || needs.deploy.result == 'failure' }}\n        run: |\n          echo \u0026quot;DEPLOY_STATUS=failure\u0026quot; \u0026gt;\u0026gt; $GITHUB_OUTPUT\n\n      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action\n      - name: Create a deployment status\n        env:\n          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}\n          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}\n        run: |\n          if [ -z \u0026quot;${DEPLOY_STATUS}\u0026quot; ]; then\n            DEPLOY_STATUS=\u0026quot;success\u0026quot;\n          fi\n\n          gh api \\\n            --method POST \\\n            \u0026quot;repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\u0026quot; \\\n            -f environment=\u0026quot;${ENVIRONMENT}\u0026quot; \\\n            -f state=\u0026quot;${DEPLOY_STATUS}\u0026quot;\n\n      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action\n      - name: Remove a non-sticky lock\n        env:\n          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}\n          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          ISSUE_NUMBER: ${{ github.event.issue.number }}\n          LOCK_ACTOR: ${{ github.actor }}\n          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}\n        run: |\n          if [ -z \u0026quot;${LOCK_REF_SHA}\u0026quot; ]; then\n            echo \u0026quot;No captured deployment lock remains\u0026quot;\n            exit 0\n          fi\n\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          lock_contents=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\u0026quot; --jq '.content' | base64 --decode)\u0026quot;\n          lock_link=\u0026quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\u0026quot;\n\n          if ! printf '%s' \u0026quot;$lock_contents\u0026quot; | jq -e \\\n            --arg actor \u0026quot;$LOCK_ACTOR\u0026quot; \\\n            --arg environment \u0026quot;$ENVIRONMENT\u0026quot; \\\n            --arg link \u0026quot;$lock_link\u0026quot; \\\n            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\n            echo \u0026quot;The captured deployment lock is sticky or belongs to another deployment\u0026quot;\n            exit 0\n          fi\n\n          repository_id=\u0026quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\u0026quot;\n          if gh api graphql \\\n            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \u0026quot;0000000000000000000000000000000000000000\u0026quot;}]}) { clientMutationId } }' \\\n            -f repository=\u0026quot;$repository_id\u0026quot; \\\n            -f name=\u0026quot;refs/heads/${lock_branch}\u0026quot; \\\n            -f before=\u0026quot;$LOCK_REF_SHA\u0026quot; \u0026gt;/dev/null; then\n            echo \u0026quot;Removed the original deployment lock\u0026quot;\n          else\n            echo \u0026quot;::warning::The original deployment lock changed; leaving the current lock in place\u0026quot;\n          fi\n\n      # remove the default 'eyes' reaction from the comment that triggered the deployment\n      # this reaction is added by the branch-deploy action by default\n      - name: remove eyes reaction\n        env:\n          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}\n        run: |\n          if [ -n \u0026quot;${INITIAL_REACTION_ID}\u0026quot; ]; then\n            gh api \\\n              --method DELETE \\\n              \u0026quot;repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\u0026quot;\n          fi\n\n      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment\n      - name: rocket reaction\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\n        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7\n        with:\n          comment-id: ${{ needs.trigger.outputs.comment_id }}\n          reactions: rocket\n\n      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment\n      - name: failure reaction\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\n        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7\n        with:\n          comment-id: ${{ needs.trigger.outputs.comment_id }}\n          reactions: '-1'\n\n      # if the deployment was successful, add a 'success' comment\n      - name: success comment\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\n        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1\n        with:\n          issue-number: ${{ github.event.issue.number }}\n          body: |\n            ### Deployment Results ✅\n\n            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\n\n      # if the deployment was not successful, add a 'failure' comment\n      - name: failure comment\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\n        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1\n        with:\n          issue-number: ${{ github.event.issue.number }}\n          body: |\n            ### Deployment Results ❌\n\n            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003etrigger\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eoutputs\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003econtinue\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003enoop\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.noop }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003edeployment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.deployment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003elock_ref_sha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.capture-lock.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003esha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003ecomment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.comment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003einitial_reaction_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.initial_reaction_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eactor_handle\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.actor_handle }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003etrigger\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e.deploy\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eskip_completing\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrue \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e we will complete the deployment manually\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCapture deployment lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecapture-lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u0026gt;/dev/null)\"; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            printf 'sha=%s\\n' \"$lock_ref_sha\" \u0026gt;\u0026gt; \"$GITHUB_OUTPUT\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrigger\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.continue == 'true' \u0026amp;\u0026amp; needs.trigger.outputs.noop != 'true' }}\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e checkout the project's repository based on the commit SHA provided by the branch-deploy step\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003echeckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e You will do your own deployment here\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efake regular deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eecho \"I am doing a fake regular deploy\"\u003c/span\u003e\n\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e update the deployment result - manually complete the deployment that was created by the branch-deploy action\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003eresult\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[trigger, deploy]\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e run even on failures but only if the trigger job set continue to true\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ always() \u0026amp;\u0026amp; needs.trigger.outputs.continue == 'true' }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if a previous step failed, set a variable to use as the deployment status\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eset deployment status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy-status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.result == 'failure' || needs.deploy.result == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"DEPLOY_STATUS=failure\" \u0026gt;\u0026gt; $GITHUB_OUTPUT\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCreate a deployment status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eDEPLOYMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.deployment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eDEPLOY_STATUS\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.environment }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"${DEPLOY_STATUS}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            DEPLOY_STATUS=\"success\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          gh api \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --method POST \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \"repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f environment=\"${ENVIRONMENT}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f state=\"${DEPLOY_STATUS}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eRemove a non-sticky lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eCOMMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.environment }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eISSUE_NUMBER\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eLOCK_ACTOR\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.actor }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eLOCK_REF_SHA\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.lock_ref_sha }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"${LOCK_REF_SHA}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"No captured deployment lock remains\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if ! printf '%s' \"$lock_contents\" | jq -e \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg actor \"$LOCK_ACTOR\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg environment \"$ENVIRONMENT\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg link \"$lock_link\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"The captured deployment lock is sticky or belongs to another deployment\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if gh api graphql \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f repository=\"$repository_id\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f name=\"refs/heads/${lock_branch}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f before=\"$LOCK_REF_SHA\" \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"Removed the original deployment lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e remove the default 'eyes' reaction from the comment that triggered the deployment\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this reaction is added by the branch-deploy action by default\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eremove eyes reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eCOMMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eINITIAL_REACTION_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.initial_reaction_id }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -n \"${INITIAL_REACTION_ID}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            gh api \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              --method DELETE \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              \"repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003erocket reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ecomment-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ereactions\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003erocket\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efailure reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ecomment-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ereactions\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e-1\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was successful, add a 'success' comment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esuccess comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epeter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.1.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eissue-number\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ebody\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            ### Deployment Results ✅\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was not successful, add a 'failure' comment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efailure comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epeter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.1.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eissue-number\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ebody\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            ### Deployment Results ❌\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMultiple Jobs with GitHub Pages and Hugo\u003c/h2\u003e\u003ca id=\"user-content-multiple-jobs-with-github-pages-and-hugo\" class=\"anchor\" aria-label=\"Permalink: Multiple Jobs with GitHub Pages and Hugo\" href=\"#multiple-jobs-with-github-pages-and-hugo\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments. This example showcases building a static site with \u003ca href=\"https://gohugo.io/\" rel=\"nofollow\"\u003ehugo\u003c/a\u003e and deploying it to \u003ca href=\"https://pages.github.com/\"\u003eGitHub Pages\u003c/a\u003e.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eThis live example can be found \u003ca href=\"https://github.com/GrantBirki/blog/blob/559b9be5cc3eac923be5d7923ec9a0b50429ced2/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch deploy\n\n# The workflow to execute on is comments that are newly created\non:\n  issue_comment:\n    types: [created]\n\n# Permissions needed for reacting and adding comments for IssueOps commands\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n\n# set an environment variable for use in the jobs pointing to my blog\nenv:\n  blog_url: https://test.example.com # \u0026lt;--- CHANGE THIS TO YOUR BLOG URL\n\njobs:\n  # branch-deploy trigger job\n  trigger:\n    if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings\n      ${{ github.event.issue.pull_request \u0026amp;\u0026amp;\n      (contains(github.event.comment.body, '.deploy') ||\n      contains(github.event.comment.body, '.lock') ||\n      contains(github.event.comment.body, '.noop') ||\n      contains(github.event.comment.body, '.help') ||\n      contains(github.event.comment.body, '.wcid') ||\n      contains(github.event.comment.body, '.unlock')) }}\n    runs-on: ubuntu-latest\n    outputs: # set outputs for use in downstream jobs\n      continue: ${{ steps.branch-deploy.outputs.continue }}\n      noop: ${{ steps.branch-deploy.outputs.noop }}\n      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}\n      environment: ${{ steps.branch-deploy.outputs.environment }}\n      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}\n      sha: ${{ steps.branch-deploy.outputs.sha }}\n      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}\n      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}\n      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}\n\n    steps:\n      # execute the branch-deploy action\n      - uses: github/branch-deploy@vX.X.X\n        id: branch-deploy\n        with:\n          trigger: '.deploy'\n          environment: 'github-pages'\n          production_environments: 'github-pages'\n          skip_completing: true # we will complete the deployment manually in the 'result' job\n          admins: 'false' # \u0026lt;--- add your GitHub username here (if you want to use the admins feature)\n\n      - name: Capture deployment lock\n        id: capture-lock\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n        run: |\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          if lock_ref_sha=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}\u0026quot; --jq '.object.sha' 2\u0026gt;/dev/null)\u0026quot;; then\n            printf 'sha=%s\\n' \u0026quot;$lock_ref_sha\u0026quot; \u0026gt;\u0026gt; \u0026quot;$GITHUB_OUTPUT\u0026quot;\n          else\n            echo \u0026quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\u0026quot;\n          fi\n\n  # build the github-pages site with hugo\n  build:\n    needs: trigger\n    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true\n    runs-on: ubuntu-latest\n\n    steps:\n      # checkout the project's repository based on the commit SHA provided by the branch-deploy step\n      - name: checkout\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ needs.trigger.outputs.sha }}\n          persist-credentials: false\n\n      # read the hugo version from the .hugo-version file in this repository\n      - name: set hugo version\n        id: hugo-version\n        run: |\n          HUGO_VERSION=$(cat .hugo-version)\n          echo \u0026quot;HUGO_VERSION=${HUGO_VERSION}\u0026quot; \u0026gt;\u0026gt; $GITHUB_OUTPUT\n\n      # install the hugo cli using the version detected in the previous step\n      - name: install hugo cli\n        env:\n          HUGO_VERSION: ${{ steps.hugo-version.outputs.HUGO_VERSION }}\n        run: |\n          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.deb \\\n          \u0026amp;\u0026amp; sudo dpkg -i ${{ runner.temp }}/hugo.deb\n\n      # configure the GitHub Pages action\n      - name: setup pages\n        id: pages\n        uses: actions/configure-pages@c5a3e1159e0cbdf0845eb8811bd39e39fc3099c2 # pin@v2.1.3\n\n      # build the site with hugo\n      - name: build with hugo\n        env:\n          BASE_URL: ${{ steps.pages.outputs.base_url }}\n        run: |\n          hugo --gc --verbose \\\n            --baseURL \u0026quot;$BASE_URL\u0026quot;\n\n      # this step is custom to my blog and adds a 'commit' version to the site\n      - name: write build version\n        run: echo ${GITHUB_SHA} \u0026gt; ./public/version.txt\n\n      # upload the built site as an artifact for the deploy step\n      - name: upload artifact\n        uses: actions/upload-pages-artifact@253fd476ed429e83b7aae64a92a75b4ceb1a17cf # pin@v1.0.7\n        with:\n          path: ./public\n\n  # deploy to GitHub Pages\n  deploy:\n    needs: [trigger, build]\n    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    runs-on: ubuntu-latest\n\n    steps:\n      # deploy the site to GitHub Pages\n      - name: deploy\n        id: deployment\n        uses: actions/deploy-pages@20a4baa1095bad40ba7d6ca0d9abbc220b76603f # pin@v1.2.3\n\n  # update the deployment result - manually complete the deployment that was created by the branch-deploy action\n  result:\n    needs: [trigger, build, deploy]\n    runs-on: ubuntu-latest\n    # run even on failures but only if the trigger job set continue to true\n    if: ${{ always() \u0026amp;\u0026amp; needs.trigger.outputs.continue == 'true' }}\n\n    steps:\n      # if a previous step failed, set a variable to use as the deployment status\n      - name: set deployment status\n        id: deploy-status\n        if:\n          ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||\n          needs.deploy.result == 'failure' }}\n        run: |\n          echo \u0026quot;DEPLOY_STATUS=failure\u0026quot; \u0026gt;\u0026gt; $GITHUB_OUTPUT\n\n      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action\n      - name: Create a deployment status\n        env:\n          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}\n          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}\n        run: |\n          if [ -z \u0026quot;${DEPLOY_STATUS}\u0026quot; ]; then\n            DEPLOY_STATUS=\u0026quot;success\u0026quot;\n          fi\n\n          gh api \\\n            --method POST \\\n            \u0026quot;repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\u0026quot; \\\n            -f environment=\u0026quot;${ENVIRONMENT}\u0026quot; \\\n            -f state=\u0026quot;${DEPLOY_STATUS}\u0026quot;\n\n      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action\n      - name: Remove a non-sticky lock\n        env:\n          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}\n          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          ISSUE_NUMBER: ${{ github.event.issue.number }}\n          LOCK_ACTOR: ${{ github.actor }}\n          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}\n        run: |\n          if [ -z \u0026quot;${LOCK_REF_SHA}\u0026quot; ]; then\n            echo \u0026quot;No captured deployment lock remains\u0026quot;\n            exit 0\n          fi\n\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          lock_contents=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\u0026quot; --jq '.content' | base64 --decode)\u0026quot;\n          lock_link=\u0026quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\u0026quot;\n\n          if ! printf '%s' \u0026quot;$lock_contents\u0026quot; | jq -e \\\n            --arg actor \u0026quot;$LOCK_ACTOR\u0026quot; \\\n            --arg environment \u0026quot;$ENVIRONMENT\u0026quot; \\\n            --arg link \u0026quot;$lock_link\u0026quot; \\\n            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\n            echo \u0026quot;The captured deployment lock is sticky or belongs to another deployment\u0026quot;\n            exit 0\n          fi\n\n          repository_id=\u0026quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\u0026quot;\n          if gh api graphql \\\n            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \u0026quot;0000000000000000000000000000000000000000\u0026quot;}]}) { clientMutationId } }' \\\n            -f repository=\u0026quot;$repository_id\u0026quot; \\\n            -f name=\u0026quot;refs/heads/${lock_branch}\u0026quot; \\\n            -f before=\u0026quot;$LOCK_REF_SHA\u0026quot; \u0026gt;/dev/null; then\n            echo \u0026quot;Removed the original deployment lock\u0026quot;\n          else\n            echo \u0026quot;::warning::The original deployment lock changed; leaving the current lock in place\u0026quot;\n          fi\n\n      # remove the default 'eyes' reaction from the comment that triggered the deployment\n      # this reaction is added by the branch-deploy action by default\n      - name: remove eyes reaction\n        env:\n          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}\n        run: |\n          if [ -n \u0026quot;${INITIAL_REACTION_ID}\u0026quot; ]; then\n            gh api \\\n              --method DELETE \\\n              \u0026quot;repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\u0026quot;\n          fi\n\n      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment\n      - name: rocket reaction\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\n        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7\n        with:\n          comment-id: ${{ needs.trigger.outputs.comment_id }}\n          reactions: rocket\n\n      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment\n      - name: failure reaction\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\n        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7\n        with:\n          comment-id: ${{ needs.trigger.outputs.comment_id }}\n          reactions: '-1'\n\n      # if the deployment was successful, add a 'success' comment\n      - name: success comment\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\n        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1\n        with:\n          issue-number: ${{ github.event.issue.number }}\n          body: |\n            ### Deployment Results ✅\n\n            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\n\n            \u0026gt; [View Live Deployment](${{ env.blog_url }}) :link:\n\n      # if the deployment was not successful, add a 'failure' comment\n      - name: failure comment\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\n        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1\n        with:\n          issue-number: ${{ github.event.issue.number }}\n          body: |\n            ### Deployment Results ❌\n\n            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The workflow to execute on is comments that are newly created\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Permissions needed for reacting and adding comments for IssueOps commands\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e set an environment variable for use in the jobs pointing to my blog\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eblog_url\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ehttps://test.example.com \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e \u0026lt;--- CHANGE THIS TO YOUR BLOG URL\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e branch-deploy trigger job\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003etrigger\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments and very specific comment body string as defined in our branch-deploy settings\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request \u0026amp;\u0026amp;\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e(contains(github.event.comment.body, '.deploy') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.lock') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.noop') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.help') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.wcid') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.unlock')) }}\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eoutputs\u003c/span\u003e: \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e set outputs for use in downstream jobs\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003econtinue\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003enoop\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.noop }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003edeployment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.deployment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003elock_ref_sha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.capture-lock.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003esha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003ecomment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.comment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003einitial_reaction_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.initial_reaction_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eactor_handle\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.actor_handle }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e execute the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003etrigger\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e.deploy\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003egithub-pages\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eproduction_environments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003egithub-pages\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eskip_completing\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrue \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e we will complete the deployment manually in the 'result' job\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eadmins\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003efalse\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e \u0026lt;--- add your GitHub username here (if you want to use the admins feature)\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCapture deployment lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecapture-lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u0026gt;/dev/null)\"; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            printf 'sha=%s\\n' \"$lock_ref_sha\" \u0026gt;\u0026gt; \"$GITHUB_OUTPUT\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e build the github-pages site with hugo\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003ebuild\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrigger\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.continue == 'true' }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run if the trigger job set continue to true\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e checkout the project's repository based on the commit SHA provided by the branch-deploy step\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003echeckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e read the hugo version from the .hugo-version file in this repository\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eset hugo version\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ehugo-version\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          HUGO_VERSION=$(cat .hugo-version)\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"HUGO_VERSION=${HUGO_VERSION}\" \u0026gt;\u0026gt; $GITHUB_OUTPUT\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e install the hugo cli using the version detected in the previous step\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003einstall hugo cli\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eHUGO_VERSION\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.hugo-version.outputs.HUGO_VERSION }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.deb \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          \u0026amp;\u0026amp; sudo dpkg -i ${{ runner.temp }}/hugo.deb\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e configure the GitHub Pages action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esetup pages\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epages\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/configure-pages@c5a3e1159e0cbdf0845eb8811bd39e39fc3099c2 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.1.3\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e build the site with hugo\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebuild with hugo\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eBASE_URL\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.pages.outputs.base_url }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          hugo --gc --verbose \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --baseURL \"$BASE_URL\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this step is custom to my blog and adds a 'commit' version to the site\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite build version\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eecho ${GITHUB_SHA} \u0026gt; ./public/version.txt\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e upload the built site as an artifact for the deploy step\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eupload artifact\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/upload-pages-artifact@253fd476ed429e83b7aae64a92a75b4ceb1a17cf \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v1.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003epath\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e./public\u003c/span\u003e\n\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e deploy to GitHub Pages\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[trigger, build]\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.continue == 'true' }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run if the trigger job set continue to true\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub-pages\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eurl\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deployment.outputs.page_url }}\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e deploy the site to GitHub Pages\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeployment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/deploy-pages@20a4baa1095bad40ba7d6ca0d9abbc220b76603f \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v1.2.3\u003c/span\u003e\n\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e update the deployment result - manually complete the deployment that was created by the branch-deploy action\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003eresult\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[trigger, build, deploy]\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e run even on failures but only if the trigger job set continue to true\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ always() \u0026amp;\u0026amp; needs.trigger.outputs.continue == 'true' }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if a previous step failed, set a variable to use as the deployment status\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eset deployment status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy-status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e:\n          \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||\u003c/span\u003e\n          \u003cspan class=\"pl-s\"\u003eneeds.deploy.result == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"DEPLOY_STATUS=failure\" \u0026gt;\u0026gt; $GITHUB_OUTPUT\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCreate a deployment status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eDEPLOYMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.deployment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eDEPLOY_STATUS\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.environment }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"${DEPLOY_STATUS}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            DEPLOY_STATUS=\"success\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          gh api \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --method POST \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \"repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f environment=\"${ENVIRONMENT}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f state=\"${DEPLOY_STATUS}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eRemove a non-sticky lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eCOMMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.environment }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eISSUE_NUMBER\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eLOCK_ACTOR\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.actor }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eLOCK_REF_SHA\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.lock_ref_sha }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"${LOCK_REF_SHA}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"No captured deployment lock remains\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if ! printf '%s' \"$lock_contents\" | jq -e \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg actor \"$LOCK_ACTOR\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg environment \"$ENVIRONMENT\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg link \"$lock_link\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"The captured deployment lock is sticky or belongs to another deployment\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if gh api graphql \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f repository=\"$repository_id\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f name=\"refs/heads/${lock_branch}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f before=\"$LOCK_REF_SHA\" \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"Removed the original deployment lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e remove the default 'eyes' reaction from the comment that triggered the deployment\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this reaction is added by the branch-deploy action by default\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eremove eyes reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eCOMMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eINITIAL_REACTION_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.initial_reaction_id }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -n \"${INITIAL_REACTION_ID}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            gh api \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              --method DELETE \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              \"repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003erocket reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ecomment-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ereactions\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003erocket\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efailure reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ecomment-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ereactions\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e-1\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was successful, add a 'success' comment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esuccess comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epeter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.1.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eissue-number\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ebody\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            ### Deployment Results ✅\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026gt; [View Live Deployment](${{ env.blog_url }}) :link:\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was not successful, add a 'failure' comment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efailure comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epeter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.1.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eissue-number\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ebody\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            ### Deployment Results ❌\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMultiple Jobs with GitHub Pages and Astro\u003c/h2\u003e\u003ca id=\"user-content-multiple-jobs-with-github-pages-and-astro\" class=\"anchor\" aria-label=\"Permalink: Multiple Jobs with GitHub Pages and Astro\" href=\"#multiple-jobs-with-github-pages-and-astro\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments - Using \u003ca href=\"https://astro.build\" rel=\"nofollow\"\u003eAstro\u003c/a\u003e to create a static site and deploying to \u003ca href=\"https://pages.github.com/\"\u003eGitHub Pages\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eA live example can be found \u003ca href=\"https://github.com/GrantBirki/astrowind-hard-fork/blob/be29d05cc0f3fe04e37ade9d38c653ed55c6cf53/.github/workflows/branch-deploy.yml\"\u003ehere\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: branch deploy\n\n# The workflow to execute on is comments that are newly created\non:\n  issue_comment:\n    types: [created]\n\n# Permissions needed for reacting and adding comments for IssueOps commands\npermissions:\n  pull-requests: write\n  deployments: write\n  contents: write\n  checks: read\n  statuses: read\n  pages: write\n  id-token: write\n\n# set an environment variable for use in the jobs pointing the site_url\nenv:\n  site_url: https://test.example.com # \u0026lt;--- change this to your site url\n\njobs:\n  # branch-deploy trigger job\n  trigger:\n    if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings\n      ${{ github.event.issue.pull_request \u0026amp;\u0026amp;\n      (contains(github.event.comment.body, '.deploy') ||\n      contains(github.event.comment.body, '.lock') ||\n      contains(github.event.comment.body, '.noop') ||\n      contains(github.event.comment.body, '.help') ||\n      contains(github.event.comment.body, '.wcid') ||\n      contains(github.event.comment.body, '.unlock')) }}\n    runs-on: ubuntu-latest\n    outputs: # set outputs for use in downstream jobs\n      continue: ${{ steps.branch-deploy.outputs.continue }}\n      noop: ${{ steps.branch-deploy.outputs.noop }}\n      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}\n      environment: ${{ steps.branch-deploy.outputs.environment }}\n      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}\n      sha: ${{ steps.branch-deploy.outputs.sha }}\n      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}\n      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}\n      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}\n\n    steps:\n      # execute the branch-deploy action\n      - uses: github/branch-deploy@vX.X.X\n        id: branch-deploy\n        with:\n          trigger: '.deploy'\n          environment: 'github-pages'\n          production_environments: 'github-pages'\n          environment_targets: 'github-pages'\n          skip_completing: true # we will complete the deployment manually in the 'result' job\n          admins: 'false' # \u0026lt;--- add your GitHub username here (if you want to use the admins feature)\n\n      - name: Capture deployment lock\n        id: capture-lock\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n        run: |\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          if lock_ref_sha=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}\u0026quot; --jq '.object.sha' 2\u0026gt;/dev/null)\u0026quot;; then\n            printf 'sha=%s\\n' \u0026quot;$lock_ref_sha\u0026quot; \u0026gt;\u0026gt; \u0026quot;$GITHUB_OUTPUT\u0026quot;\n          else\n            echo \u0026quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\u0026quot;\n          fi\n\n  # build the github-pages site with Astro\n  build:\n    needs: trigger\n    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: checkout\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ needs.trigger.outputs.sha }}\n          persist-credentials: false\n\n      - name: build with astro\n        uses: withastro/action@e3193ac80e18917ceaeb9f2d47019ad3b2c0416a # pin@v0.3.0\n\n  # deploy to GitHub Pages\n  deploy:\n    needs: [trigger, build]\n    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    runs-on: ubuntu-latest\n\n    steps:\n      # deploy the site to GitHub Pages\n      - name: deploy\n        id: deployment\n        uses: actions/deploy-pages@497da40f5225e762159b457c9ae5d6f75a136f5c # pin@v1.2.5\n\n  # update the deployment result - manually complete the deployment that was created by the branch-deploy action\n  result:\n    needs: [trigger, build, deploy]\n    runs-on: ubuntu-latest\n    # run even on failures but only if the trigger job set continue to true\n    if: ${{ always() \u0026amp;\u0026amp; needs.trigger.outputs.continue == 'true' }}\n\n    steps:\n      # if a previous step failed, set a variable to use as the deployment status\n      - name: set deployment status\n        id: deploy-status\n        if:\n          ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||\n          needs.deploy.result == 'failure' }}\n        run: |\n          echo \u0026quot;DEPLOY_STATUS=failure\u0026quot; \u0026gt;\u0026gt; $GITHUB_OUTPUT\n\n      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action\n      - name: Create a deployment status\n        env:\n          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}\n          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}\n        run: |\n          if [ -z \u0026quot;${DEPLOY_STATUS}\u0026quot; ]; then\n            DEPLOY_STATUS=\u0026quot;success\u0026quot;\n          fi\n\n          gh api \\\n            --method POST \\\n            \u0026quot;repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\u0026quot; \\\n            -f environment=\u0026quot;${ENVIRONMENT}\u0026quot; \\\n            -f state=\u0026quot;${DEPLOY_STATUS}\u0026quot;\n\n      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action\n      - name: Remove a non-sticky lock\n        env:\n          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}\n          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          ISSUE_NUMBER: ${{ github.event.issue.number }}\n          LOCK_ACTOR: ${{ github.actor }}\n          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}\n        run: |\n          if [ -z \u0026quot;${LOCK_REF_SHA}\u0026quot; ]; then\n            echo \u0026quot;No captured deployment lock remains\u0026quot;\n            exit 0\n          fi\n\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          lock_contents=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\u0026quot; --jq '.content' | base64 --decode)\u0026quot;\n          lock_link=\u0026quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\u0026quot;\n\n          if ! printf '%s' \u0026quot;$lock_contents\u0026quot; | jq -e \\\n            --arg actor \u0026quot;$LOCK_ACTOR\u0026quot; \\\n            --arg environment \u0026quot;$ENVIRONMENT\u0026quot; \\\n            --arg link \u0026quot;$lock_link\u0026quot; \\\n            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\n            echo \u0026quot;The captured deployment lock is sticky or belongs to another deployment\u0026quot;\n            exit 0\n          fi\n\n          repository_id=\u0026quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\u0026quot;\n          if gh api graphql \\\n            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \u0026quot;0000000000000000000000000000000000000000\u0026quot;}]}) { clientMutationId } }' \\\n            -f repository=\u0026quot;$repository_id\u0026quot; \\\n            -f name=\u0026quot;refs/heads/${lock_branch}\u0026quot; \\\n            -f before=\u0026quot;$LOCK_REF_SHA\u0026quot; \u0026gt;/dev/null; then\n            echo \u0026quot;Removed the original deployment lock\u0026quot;\n          else\n            echo \u0026quot;::warning::The original deployment lock changed; leaving the current lock in place\u0026quot;\n          fi\n\n      # remove the default 'eyes' reaction from the comment that triggered the deployment\n      # this reaction is added by the branch-deploy action by default\n      - name: remove eyes reaction\n        env:\n          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}\n        run: |\n          if [ -n \u0026quot;${INITIAL_REACTION_ID}\u0026quot; ]; then\n            gh api \\\n              --method DELETE \\\n              \u0026quot;repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\u0026quot;\n          fi\n\n      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment\n      - name: rocket reaction\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\n        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7\n        with:\n          comment-id: ${{ needs.trigger.outputs.comment_id }}\n          reactions: rocket\n\n      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment\n      - name: failure reaction\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\n        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7\n        with:\n          comment-id: ${{ needs.trigger.outputs.comment_id }}\n          reactions: '-1'\n\n      # if the deployment was successful, add a 'success' comment\n      - name: success comment\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\n        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1\n        with:\n          issue-number: ${{ github.event.issue.number }}\n          body: |\n            ### Deployment Results ✅\n\n            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\n\n            \u0026gt; [View Live Deployment](${{ env.site_url }}) :link:\n\n      # if the deployment was not successful, add a 'failure' comment\n      - name: failure comment\n        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\n        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1\n        with:\n          issue-number: ${{ github.event.issue.number }}\n          body: |\n            ### Deployment Results ❌\n\n            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The workflow to execute on is comments that are newly created\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[created]\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Permissions needed for reacting and adding comments for IssueOps commands\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003epages\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003eid-token\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e set an environment variable for use in the jobs pointing the site_url\u003c/span\u003e\n\u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003esite_url\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ehttps://test.example.com \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e \u0026lt;--- change this to your site url\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e branch-deploy trigger job\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003etrigger\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run on pull request comments and very specific comment body string as defined in our branch-deploy settings\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request \u0026amp;\u0026amp;\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e(contains(github.event.comment.body, '.deploy') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.lock') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.noop') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.help') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.wcid') ||\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003econtains(github.event.comment.body, '.unlock')) }}\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eoutputs\u003c/span\u003e: \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e set outputs for use in downstream jobs\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003econtinue\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003enoop\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.noop }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003edeployment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.deployment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003elock_ref_sha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.capture-lock.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003esha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003ecomment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.comment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003einitial_reaction_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.initial_reaction_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eactor_handle\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.actor_handle }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e execute the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003etrigger\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e.deploy\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003egithub-pages\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eproduction_environments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003egithub-pages\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eenvironment_targets\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003egithub-pages\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eskip_completing\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrue \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e we will complete the deployment manually in the 'result' job\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eadmins\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003efalse\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e \u0026lt;--- add your GitHub username here (if you want to use the admins feature)\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCapture deployment lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecapture-lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u0026gt;/dev/null)\"; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            printf 'sha=%s\\n' \"$lock_ref_sha\" \u0026gt;\u0026gt; \"$GITHUB_OUTPUT\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e build the github-pages site with Astro\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003ebuild\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etrigger\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.continue == 'true' }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run if the trigger job set continue to true\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003echeckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebuild with astro\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewithastro/action@e3193ac80e18917ceaeb9f2d47019ad3b2c0416a \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v0.3.0\u003c/span\u003e\n\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e deploy to GitHub Pages\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[trigger, build]\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.continue == 'true' }} \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e only run if the trigger job set continue to true\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub-pages\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eurl\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deployment.outputs.page_url }}\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e deploy the site to GitHub Pages\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeployment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/deploy-pages@497da40f5225e762159b457c9ae5d6f75a136f5c \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v1.2.5\u003c/span\u003e\n\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e update the deployment result - manually complete the deployment that was created by the branch-deploy action\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003eresult\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e[trigger, build, deploy]\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e run even on failures but only if the trigger job set continue to true\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ always() \u0026amp;\u0026amp; needs.trigger.outputs.continue == 'true' }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if a previous step failed, set a variable to use as the deployment status\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eset deployment status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeploy-status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e:\n          \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||\u003c/span\u003e\n          \u003cspan class=\"pl-s\"\u003eneeds.deploy.result == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"DEPLOY_STATUS=failure\" \u0026gt;\u0026gt; $GITHUB_OUTPUT\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCreate a deployment status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eDEPLOYMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.deployment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eDEPLOY_STATUS\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.environment }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"${DEPLOY_STATUS}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            DEPLOY_STATUS=\"success\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          gh api \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --method POST \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \"repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f environment=\"${ENVIRONMENT}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f state=\"${DEPLOY_STATUS}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eRemove a non-sticky lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eCOMMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.environment }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eISSUE_NUMBER\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eLOCK_ACTOR\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.actor }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eLOCK_REF_SHA\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.lock_ref_sha }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"${LOCK_REF_SHA}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"No captured deployment lock remains\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if ! printf '%s' \"$lock_contents\" | jq -e \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg actor \"$LOCK_ACTOR\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg environment \"$ENVIRONMENT\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg link \"$lock_link\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"The captured deployment lock is sticky or belongs to another deployment\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if gh api graphql \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f repository=\"$repository_id\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f name=\"refs/heads/${lock_branch}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f before=\"$LOCK_REF_SHA\" \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"Removed the original deployment lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e remove the default 'eyes' reaction from the comment that triggered the deployment\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e this reaction is added by the branch-deploy action by default\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eremove eyes reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eCOMMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eINITIAL_REACTION_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.initial_reaction_id }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -n \"${INITIAL_REACTION_ID}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            gh api \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              --method DELETE \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              \"repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003erocket reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ecomment-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ereactions\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003erocket\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efailure reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ecomment-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.trigger.outputs.comment_id }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ereactions\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e-1\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was successful, add a 'success' comment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esuccess comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epeter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.1.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eissue-number\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ebody\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            ### Deployment Results ✅\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026gt; [View Live Deployment](${{ env.site_url }}) :link:\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if the deployment was not successful, add a 'failure' comment\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efailure comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003epeter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.1.1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eissue-number\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ebody\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            ### Deployment Results ❌\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMultiple Jobs with GitHub Environments\u003c/h2\u003e\u003ca id=\"user-content-multiple-jobs-with-github-environments\" class=\"anchor\" aria-label=\"Permalink: Multiple Jobs with GitHub Environments\" href=\"#multiple-jobs-with-github-environments\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA detailed example using multiple jobs, \u003ca href=\"https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment\"\u003erepository environments\u003c/a\u003e, and Terraform. As mentioned in the \u003ca href=\"https://github.com/github/branch-deploy#about-environments-\"\u003eREADME\u003c/a\u003e, a deployment completes when the workflow targeting that environment completes. In this example, the branch deployment action targets a separate environment than the \"actual\" deployment logic, which lets us control the completion of the branch deployment while being able to manage environments separately.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"name: Branch Deploy\n\non:\n  issue_comment:\n    types:\n      - created\n\nenv:\n  # These variables are scoped to the **repository**.\n  TF_VAR_image_repository: ${{ vars.IMAGE_REPOSITORY }}\n\npermissions:\n  checks: read\n  statuses: read\n  contents: write\n  deployments: write\n  packages: read\n  pull-requests: write\n\njobs:\n  start:\n    name: Start Branch Deployment\n    runs-on: ubuntu-latest\n\n    # Only start branch deployments on pull request comments.\n    if: ${{ github.event.issue.pull_request }}\n\n    # The deployments environment is used by the branch-deploy workflow.\n    environment: deployments\n\n    # Set the outputs to be used by the rest of the workflow.\n    outputs:\n      continue: ${{ steps.branch-deploy.outputs.continue }}\n      noop: ${{ steps.branch-deploy.outputs.noop }}\n      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}\n      environment: ${{ steps.branch-deploy.outputs.environment }}\n      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}\n      sha: ${{ steps.branch-deploy.outputs.sha }}\n      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}\n      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}\n      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}\n\n    steps:\n      - name: Start Branch Deployment\n        id: branch-deploy\n        uses: github/branch-deploy@vX.X.X\n        with:\n          environment: development\n          environment_targets: development,staging,production\n          skip_completing: true\n\n      - name: Capture deployment lock\n        id: capture-lock\n        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}\n        env:\n          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}\n          GH_REPO: ${{ github.repository }}\n          GH_TOKEN: ${{ github.token }}\n        run: |\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          if lock_ref_sha=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}\u0026quot; --jq '.object.sha' 2\u0026gt;/dev/null)\u0026quot;; then\n            printf 'sha=%s\\n' \u0026quot;$lock_ref_sha\u0026quot; \u0026gt;\u0026gt; \u0026quot;$GITHUB_OUTPUT\u0026quot;\n          else\n            echo \u0026quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\u0026quot;\n          fi\n\n  # This is the \u0026quot;actual\u0026quot; deployment logic. It uses the environment specified in\n  # the branch deployment comment (e.g. `.deploy to development`).\n  deploy:\n    needs: start\n\n    name: Deploy\n    runs-on: ubuntu-latest\n\n    # Only start after the branch deployment has initialized.\n    if: ${{ needs.start.outputs.continue == 'true' }}\n\n    # Use the environment specified by the `.noop` or `.deploy` comment.\n    environment: ${{ needs.start.outputs.environment }}\n\n    # Set the default working directory to `tf/` (or wherever your Terraform\n    # code is located in your repository).\n    defaults:\n      run:\n        working-directory: tf/\n\n    # Set the deployment outcome based on if `terraform plan` (.noop) or\n    # `terraform apply` (.deploy) succeeded. Defaults to 'failure'.\n    outputs:\n      outcome: ${{ (steps.plan.outcome == 'success' || steps.apply.outcome == 'success') \u0026amp;\u0026amp; 'success' || 'failure' }}\n\n    # These variables/secrets are scoped to the **environment**.\n    env:\n      ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}\n      ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}\n      ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}\n      TF_VAR_location: ${{ vars.AZURE_LOCATION }}\n\n    steps:\n      - name: Checkout\n        id: checkout\n        uses: actions/checkout@v7.0.0\n        with:\n          ref: ${{ needs.start.outputs.sha }}\n          persist-credentials: false\n\n      # Authenticate to Azure using OpenID Connect.\n      - name: Authenticate to Azure (OIDC)\n        id: azure-oidc\n        uses: azure/login@v1\n        with:\n          client-id: ${{ env.ARM_CLIENT_ID }}\n          subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}\n          tenant-id: ${{ env.ARM_TENANT_ID }}\n\n      # Install Terraform on the runner.\n      - name: Setup Terraform\n        id: setup-terraform\n        uses: hashicorp/setup-terraform@v2\n        with:\n          terraform_version: 1.5.5\n\n      # This example uses separate Terraform workspaces for each environment.\n      - name: Terraform Init\n        id: terraform-init\n        env:\n          ENVIRONMENT: ${{ needs.start.outputs.environment }}\n        run: |\n          terraform init -no-color\n          terraform workspace select -or-create=true \u0026quot;$ENVIRONMENT\u0026quot;\n\n      # If this is a `.noop`, run `terraform plan` to see what would change.\n      - name: Terraform Plan\n        id: plan\n        if: ${{ needs.start.outputs.noop == 'true' }}\n        run: terraform plan -no-color\n        continue-on-error: true\n\n      # If this is a `.deploy`, run `terraform apply` to apply the changes.\n      - name: Terraform Apply\n        id: apply\n        if: ${{ needs.start.outputs.noop != 'true' }}\n        run: terraform apply -no-color -auto-approve\n        continue-on-error: true\n\n      # Get the output from the plan/apply step.\n      - name: Save Terraform Output\n        id: output\n        env:\n          PLAN_STDOUT: ${{ steps.plan.outputs.stdout }}\n          APPLY_STDOUT: ${{ steps.apply.outputs.stdout }}\n        run: |\n          if [ -z \u0026quot;$PLAN_STDOUT\u0026quot; ]\n          then\n            echo \u0026quot;$APPLY_STDOUT\u0026quot; \u0026gt; tf_output.txt\n          else\n            echo \u0026quot;$PLAN_STDOUT\u0026quot; \u0026gt; tf_output.txt\n          fi\n\n      # Upload the plan/apply output as an artifact so that it can be used in\n      # the `stop` job.\n      - name: Upload Terraform Output\n        id: upload\n        uses: actions/upload-artifact@v3\n        with:\n          name: tf_output\n          path: tf/tf_output.txt\n\n  stop:\n    needs:\n      - start\n      - deploy\n\n    name: Stop Branch Deployment\n    runs-on: ubuntu-latest\n\n    # Always run this job if the branch deployment was started.\n    if: ${{ always() \u0026amp;\u0026amp; needs.start.outputs.continue == 'true' }}\n\n    # Switch back to the deployments environment to update the branch\n    # deployment status.\n    environment: deployments\n\n    # Get the outputs from the `start` job. These are needed to finish the\n    # branch deployment, comment on the PR, update reactions, etc.\n    env:\n      ACTOR: ${{ needs.start.outputs.actor_handle }}\n      COMMENT_ID: ${{ needs.start.outputs.comment_id }}\n      DEPLOYMENT_ID: ${{ needs.start.outputs.deployment_id }}\n      DEPLOYMENT_STATUS: ${{ needs.deploy.outputs.outcome || 'failure' }}\n      ENVIRONMENT: ${{ needs.start.outputs.environment }}\n      GH_REPO: ${{ github.repository }}\n      GH_TOKEN: ${{ github.token }}\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      INITIAL_REACTION_ID: ${{ needs.start.outputs.initial_reaction_id }}\n      ISSUE_NUMBER: ${{ github.event.issue.number }}\n      LOCK_ACTOR: ${{ github.actor }}\n      LOCK_REF_SHA: ${{ needs.start.outputs.lock_ref_sha }}\n      NOOP: ${{ needs.start.outputs.noop }}\n      SHA: ${{ needs.start.outputs.sha }}\n      REPOSITORY: ${{ github.repository }}\n\n    steps:\n      # Tf this was not a `.noop` deployment, set the status.\n      - if: ${{ env.NOOP != 'true' }}\n        name: Set Deployment Status\n        id: set-status\n        run: |\n          gh api --method POST \\\n            \u0026quot;repos/${REPOSITORY}/deployments/${DEPLOYMENT_ID}/statuses\u0026quot; \\\n            -f environment=\u0026quot;${ENVIRONMENT}\u0026quot; \\\n            -f state=\u0026quot;${DEPLOYMENT_STATUS}\u0026quot;\n\n      # Remove the non-sticky lock for either a `.noop` or `.deploy`.\n      - name: Remove Non-Sticky Lock\n        id: remove-lock\n        run: |\n          if [ -z \u0026quot;${LOCK_REF_SHA}\u0026quot; ]; then\n            echo \u0026quot;No captured deployment lock remains\u0026quot;\n            exit 0\n          fi\n\n          lock_branch=\u0026quot;$(printf '%s' \u0026quot;$ENVIRONMENT\u0026quot; | jq -Rsr 'gsub(\u0026quot;\\\\s\u0026quot;; \u0026quot;-\u0026quot;)')-branch-deploy-lock\u0026quot;\n          lock_contents=\u0026quot;$(gh api --method GET \u0026quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\u0026quot; --jq '.content' | base64 --decode)\u0026quot;\n          lock_link=\u0026quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\u0026quot;\n\n          if ! printf '%s' \u0026quot;$lock_contents\u0026quot; | jq -e \\\n            --arg actor \u0026quot;$LOCK_ACTOR\u0026quot; \\\n            --arg environment \u0026quot;$ENVIRONMENT\u0026quot; \\\n            --arg link \u0026quot;$lock_link\u0026quot; \\\n            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\n            echo \u0026quot;The captured deployment lock is sticky or belongs to another deployment\u0026quot;\n            exit 0\n          fi\n\n          repository_id=\u0026quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\u0026quot;\n          if gh api graphql \\\n            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \u0026quot;0000000000000000000000000000000000000000\u0026quot;}]}) { clientMutationId } }' \\\n            -f repository=\u0026quot;$repository_id\u0026quot; \\\n            -f name=\u0026quot;refs/heads/${lock_branch}\u0026quot; \\\n            -f before=\u0026quot;$LOCK_REF_SHA\u0026quot; \u0026gt;/dev/null; then\n            echo \u0026quot;Removed the original deployment lock\u0026quot;\n          else\n            echo \u0026quot;::warning::The original deployment lock changed; leaving the current lock in place\u0026quot;\n          fi\n\n      # Remove the trigger reaction added to the user's comment.\n      - name: Remove Trigger Reaction\n        id: remove-reaction\n        run: |\n          if [ -n \u0026quot;${INITIAL_REACTION_ID}\u0026quot; ]; then\n            gh api --method DELETE \\\n              \u0026quot;repos/${REPOSITORY}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\u0026quot;\n          fi\n\n      # Add a new reaction based on if the deployment succeeded or failed.\n      - name: Add Reaction\n        id: add-reaction\n        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7\n        env:\n          REACTION: ${{ env.DEPLOYMENT_STATUS == 'success' \u0026amp;\u0026amp; 'rocket' || '-1' }}\n        with:\n          comment-id: ${{ env.COMMENT_ID }}\n          reactions: ${{ env.DEPLOYMENT_STATUS == 'success' \u0026amp;\u0026amp; 'rocket' || '-1' }}\n\n      # If the plan/apply didn't run because of a failure, this step will also\n      # fail, hence setting continue-on-error.\n      - name: Get Terraform Output Artifact\n        id: get-artifact\n        uses: actions/download-artifact@v3\n        with:\n          name: tf_output\n        continue-on-error: true\n\n      # Add a success comment, including the plan/apply output (if present).\n      - if: ${{ env.DEPLOYMENT_STATUS == 'success' }}\n        name: Add Success Comment\n        id: success-comment\n        uses: actions/github-script@v6\n        with:\n          script: |\n            const fs = require('fs')\n\n            let output\n            try { output = fs.readFileSync('tf_output.txt', 'utf8') }\n            catch (err) { output = 'No Terraform output!' }\n\n            await github.rest.issues.createComment({\n              issue_number: context.issue.number,\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              body: `### Deployment Results :white_check_mark:\n\n            **${process.env.ACTOR}** successfully ${ process.env.NOOP === 'true' ? '**noop** deployed' : 'deployed' } sha \\`${process.env.SHA}\\` to **${process.env.ENVIRONMENT}**\n\n            \u0026lt;details\u0026gt;\u0026lt;summary\u0026gt;Show Results\u0026lt;/summary\u0026gt;\n\n            \\`\\`\\`terraform\\n${ output }\\n\\`\\`\\`\n\n            \u0026lt;/details\u0026gt;`\n            })\n\n      # Add a failure comment, including the plan/apply output (if present).\n      - if: ${{ env.DEPLOYMENT_STATUS == 'failure' }}\n        name: Add Failure Comment\n        id: failure-comment\n        uses: actions/github-script@v6\n        with:\n          script: |\n            const fs = require('fs')\n\n            let output\n            try { output = fs.readFileSync('tf_output.txt', 'utf8') }\n            catch (err) { output = 'No Terraform output!' }\n\n            await github.rest.issues.createComment({\n              issue_number: context.issue.number,\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              body: `### Deployment Results :x:\n\n            **${process.env.ACTOR}** had a failure when ${ process.env.NOOP === 'true' ? '**noop** deploying' : 'deploying' } sha \\`${process.env.SHA}\\` to **${process.env.ENVIRONMENT}**\n\n            \u0026lt;details\u0026gt;\u0026lt;summary\u0026gt;Show Results\u0026lt;/summary\u0026gt;\n\n            \\`\\`\\`terraform\\n${ output }\\n\\`\\`\\`\n\n            \u0026lt;/details\u0026gt;`\n            })\n\n      # If the deployment failed, fail the workflow.\n      - if: ${{ env.DEPLOYMENT_STATUS == 'failure' }}\n        name: Fail Workflow\n        id: fail-workflow\n        run: |\n          echo \u0026quot;There was a deployment problem...failing the workflow!\u0026quot;\n          exit 1\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eBranch Deploy\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eon\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003eissue_comment\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003etypes\u003c/span\u003e:\n      - \u003cspan class=\"pl-s\"\u003ecreated\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e These variables are scoped to the **repository**.\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003eTF_VAR_image_repository\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ vars.IMAGE_REPOSITORY }}\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003epermissions\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003echecks\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003estatuses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003econtents\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeployments\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003epackages\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eread\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003epull-requests\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ewrite\u003c/span\u003e\n\n\u003cspan class=\"pl-ent\"\u003ejobs\u003c/span\u003e:\n  \u003cspan class=\"pl-ent\"\u003estart\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eStart Branch Deployment\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Only start branch deployments on pull request comments.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.pull_request }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e The deployments environment is used by the branch-deploy workflow.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeployments\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Set the outputs to be used by the rest of the workflow.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eoutputs\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003econtinue\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003enoop\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.noop }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003edeployment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.deployment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003elock_ref_sha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.capture-lock.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003esha\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003ecomment_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.comment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003einitial_reaction_id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.initial_reaction_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eactor_handle\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.actor_handle }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eStart Branch Deployment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ebranch-deploy\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003egithub/branch-deploy@vX.X.X\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edevelopment\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eenvironment_targets\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edevelopment,staging,production\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eskip_completing\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCapture deployment lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ecapture-lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.continue == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.branch-deploy.outputs.environment }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u0026gt;/dev/null)\"; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            printf 'sha=%s\\n' \"$lock_ref_sha\" \u0026gt;\u0026gt; \"$GITHUB_OUTPUT\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e This is the \"actual\" deployment logic. It uses the environment specified in\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the branch deployment comment (e.g. `.deploy to development`).\u003c/span\u003e\n  \u003cspan class=\"pl-ent\"\u003edeploy\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003estart\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eDeploy\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Only start after the branch deployment has initialized.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.continue == 'true' }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Use the environment specified by the `.noop` or `.deploy` comment.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.environment }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Set the default working directory to `tf/` (or wherever your Terraform\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e code is located in your repository).\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003edefaults\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e:\n        \u003cspan class=\"pl-ent\"\u003eworking-directory\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etf/\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Set the deployment outcome based on if `terraform plan` (.noop) or\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e `terraform apply` (.deploy) succeeded. Defaults to 'failure'.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eoutputs\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003eoutcome\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ (steps.plan.outcome == 'success' || steps.apply.outcome == 'success') \u0026amp;\u0026amp; 'success' || 'failure' }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e These variables/secrets are scoped to the **environment**.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003eARM_CLIENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.ARM_CLIENT_ID }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eARM_SUBSCRIPTION_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.ARM_SUBSCRIPTION_ID }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eARM_TENANT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.ARM_TENANT_ID }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eTF_VAR_location\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ vars.AZURE_LOCATION }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eCheckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003echeckout\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/checkout@v7.0.0\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eref\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.sha }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epersist-credentials\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Authenticate to Azure using OpenID Connect.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eAuthenticate to Azure (OIDC)\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eazure-oidc\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eazure/login@v1\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eclient-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.ARM_CLIENT_ID }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003esubscription-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.ARM_SUBSCRIPTION_ID }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003etenant-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.ARM_TENANT_ID }}\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Install Terraform on the runner.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eSetup Terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esetup-terraform\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003ehashicorp/setup-terraform@v2\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eterraform_version\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e1.5.5\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e This example uses separate Terraform workspaces for each environment.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTerraform Init\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform-init\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.environment }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          terraform init -no-color\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          terraform workspace select -or-create=true \"$ENVIRONMENT\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If this is a `.noop`, run `terraform plan` to see what would change.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTerraform Plan\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eplan\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.noop == 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform plan -no-color\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003econtinue-on-error\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If this is a `.deploy`, run `terraform apply` to apply the changes.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eTerraform Apply\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eapply\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.noop != 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eterraform apply -no-color -auto-approve\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003econtinue-on-error\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Get the output from the plan/apply step.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eSave Terraform Output\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eoutput\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ePLAN_STDOUT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.plan.outputs.stdout }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003eAPPLY_STDOUT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ steps.apply.outputs.stdout }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"$PLAN_STDOUT\" ]\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"$APPLY_STDOUT\" \u0026gt; tf_output.txt\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"$PLAN_STDOUT\" \u0026gt; tf_output.txt\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Upload the plan/apply output as an artifact so that it can be used in\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e the `stop` job.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eUpload Terraform Output\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eupload\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/upload-artifact@v3\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etf_output\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003epath\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etf/tf_output.txt\u003c/span\u003e\n\n  \u003cspan class=\"pl-ent\"\u003estop\u003c/span\u003e:\n    \u003cspan class=\"pl-ent\"\u003eneeds\u003c/span\u003e:\n      - \u003cspan class=\"pl-s\"\u003estart\u003c/span\u003e\n      - \u003cspan class=\"pl-s\"\u003edeploy\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eStop Branch Deployment\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eruns-on\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eubuntu-latest\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Always run this job if the branch deployment was started.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ always() \u0026amp;\u0026amp; needs.start.outputs.continue == 'true' }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Switch back to the deployments environment to update the branch\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e deployment status.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenvironment\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003edeployments\u003c/span\u003e\n\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Get the outputs from the `start` job. These are needed to finish the\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e branch deployment, comment on the PR, update reactions, etc.\u003c/span\u003e\n    \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n      \u003cspan class=\"pl-ent\"\u003eACTOR\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.actor_handle }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eCOMMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.comment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eDEPLOYMENT_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.deployment_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eDEPLOYMENT_STATUS\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.deploy.outputs.outcome || 'failure' }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eENVIRONMENT\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.environment }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eGH_REPO\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eGH_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.token }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eGITHUB_TOKEN\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ secrets.GITHUB_TOKEN }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eINITIAL_REACTION_ID\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.initial_reaction_id }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eISSUE_NUMBER\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.event.issue.number }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eLOCK_ACTOR\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.actor }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eLOCK_REF_SHA\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.lock_ref_sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eNOOP\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.noop }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eSHA\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ needs.start.outputs.sha }}\u003c/span\u003e\n      \u003cspan class=\"pl-ent\"\u003eREPOSITORY\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ github.repository }}\u003c/span\u003e\n\n    \u003cspan class=\"pl-ent\"\u003esteps\u003c/span\u003e:\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Tf this was not a `.noop` deployment, set the status.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.NOOP != 'true' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eSet Deployment Status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eset-status\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          gh api --method POST \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \"repos/${REPOSITORY}/deployments/${DEPLOYMENT_ID}/statuses\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f environment=\"${ENVIRONMENT}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f state=\"${DEPLOYMENT_STATUS}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Remove the non-sticky lock for either a `.noop` or `.deploy`.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eRemove Non-Sticky Lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eremove-lock\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -z \"${LOCK_REF_SHA}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"No captured deployment lock remains\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if ! printf '%s' \"$lock_contents\" | jq -e \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg actor \"$LOCK_ACTOR\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg environment \"$ENVIRONMENT\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            --arg link \"$lock_link\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"The captured deployment lock is sticky or belongs to another deployment\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            exit 0\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if gh api graphql \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f repository=\"$repository_id\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f name=\"refs/heads/${lock_branch}\" \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            -f before=\"$LOCK_REF_SHA\" \u0026gt;/dev/null; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"Removed the original deployment lock\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          else\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Remove the trigger reaction added to the user's comment.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eRemove Trigger Reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eremove-reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          if [ -n \"${INITIAL_REACTION_ID}\" ]; then\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            gh api --method DELETE \\\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              \"repos/${REPOSITORY}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          fi\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Add a new reaction based on if the deployment succeeded or failed.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eAdd Reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eadd-reaction\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 \u003c/span\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e pin@v2.0.7\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eenv\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003eREACTION\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.DEPLOYMENT_STATUS == 'success' \u0026amp;\u0026amp; 'rocket' || '-1' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ecomment-id\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.COMMENT_ID }}\u003c/span\u003e\n          \u003cspan class=\"pl-ent\"\u003ereactions\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.DEPLOYMENT_STATUS == 'success' \u0026amp;\u0026amp; 'rocket' || '-1' }}\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the plan/apply didn't run because of a failure, this step will also\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e fail, hence setting continue-on-error.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eGet Terraform Output Artifact\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eget-artifact\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/download-artifact@v3\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003etf_output\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003econtinue-on-error\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Add a success comment, including the plan/apply output (if present).\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.DEPLOYMENT_STATUS == 'success' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eAdd Success Comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003esuccess-comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/github-script@v6\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003escript\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            const fs = require('fs')\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            let output\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            try { output = fs.readFileSync('tf_output.txt', 'utf8') }\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            catch (err) { output = 'No Terraform output!' }\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            await github.rest.issues.createComment({\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              issue_number: context.issue.number,\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              owner: context.repo.owner,\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              repo: context.repo.repo,\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              body: `### Deployment Results :white_check_mark:\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${process.env.ACTOR}** successfully ${ process.env.NOOP === 'true' ? '**noop** deployed' : 'deployed' } sha \\`${process.env.SHA}\\` to **${process.env.ENVIRONMENT}**\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026lt;details\u0026gt;\u0026lt;summary\u0026gt;Show Results\u0026lt;/summary\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \\`\\`\\`terraform\\n${ output }\\n\\`\\`\\`\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026lt;/details\u0026gt;`\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            })\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Add a failure comment, including the plan/apply output (if present).\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.DEPLOYMENT_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eAdd Failure Comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efailure-comment\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003euses\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eactions/github-script@v6\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ewith\u003c/span\u003e:\n          \u003cspan class=\"pl-ent\"\u003escript\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            const fs = require('fs')\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            let output\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            try { output = fs.readFileSync('tf_output.txt', 'utf8') }\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            catch (err) { output = 'No Terraform output!' }\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            await github.rest.issues.createComment({\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              issue_number: context.issue.number,\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              owner: context.repo.owner,\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              repo: context.repo.repo,\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e              body: `### Deployment Results :x:\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            **${process.env.ACTOR}** had a failure when ${ process.env.NOOP === 'true' ? '**noop** deploying' : 'deploying' } sha \\`${process.env.SHA}\\` to **${process.env.ENVIRONMENT}**\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026lt;details\u0026gt;\u0026lt;summary\u0026gt;Show Results\u0026lt;/summary\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \\`\\`\\`terraform\\n${ output }\\n\\`\\`\\`\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026lt;/details\u0026gt;`\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            })\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e      \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e If the deployment failed, fail the workflow.\u003c/span\u003e\n      - \u003cspan class=\"pl-ent\"\u003eif\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e${{ env.DEPLOYMENT_STATUS == 'failure' }}\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003ename\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003eFail Workflow\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003eid\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003efail-workflow\u003c/span\u003e\n        \u003cspan class=\"pl-ent\"\u003erun\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e|\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          echo \"There was a deployment problem...failing the workflow!\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          exit 1\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003chr\u003e\n\u003cp dir=\"auto\"\u003eAre you using the \u003ccode\u003ebranch-deploy\u003c/code\u003e Action and want your example included here? Open a pull request and we'll add it!\u003c/p\u003e\n\u003c/article\u003e","richTextTruncated":false,"renderedFileInfo":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"Examples","fully_qualified_name":"Examples","kind":"section_1","ident_start":2,"ident_end":10,"extent_start":0,"extent_end":75067,"ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":10}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":1907,"utf16_col":0}}},{"name":"Table of Contents","fully_qualified_name":"Table of Contents","kind":"section_2","ident_start":293,"ident_end":310,"extent_start":290,"extent_end":1039,"ident_utf16":{"start":{"line_number":6,"utf16_col":3},"end":{"line_number":6,"utf16_col":20}},"extent_utf16":{"start":{"line_number":6,"utf16_col":0},"end":{"line_number":25,"utf16_col":0}}},{"name":"Simple Example","fully_qualified_name":"Simple Example","kind":"section_2","ident_start":1042,"ident_end":1056,"extent_start":1039,"extent_end":2786,"ident_utf16":{"start":{"line_number":25,"utf16_col":3},"end":{"line_number":25,"utf16_col":17}},"extent_utf16":{"start":{"line_number":25,"utf16_col":0},"end":{"line_number":76,"utf16_col":0}}},{"name":"Terraform","fully_qualified_name":"Terraform","kind":"section_2","ident_start":2789,"ident_end":2798,"extent_start":2786,"extent_end":7775,"ident_utf16":{"start":{"line_number":76,"utf16_col":3},"end":{"line_number":76,"utf16_col":12}},"extent_utf16":{"start":{"line_number":76,"utf16_col":0},"end":{"line_number":200,"utf16_col":0}}},{"name":"Terraform with Trusted Checkouts","fully_qualified_name":"Terraform with Trusted Checkouts","kind":"section_2","ident_start":7778,"ident_end":7810,"extent_start":7775,"extent_end":18529,"ident_utf16":{"start":{"line_number":200,"utf16_col":3},"end":{"line_number":200,"utf16_col":35}},"extent_utf16":{"start":{"line_number":200,"utf16_col":0},"end":{"line_number":521,"utf16_col":0}}},{"name":"`.github/workflows/branch-deploy.yml`","fully_qualified_name":"`.github/workflows/branch-deploy.yml`","kind":"section_3","ident_start":8667,"ident_end":8704,"extent_start":8663,"extent_end":15739,"ident_utf16":{"start":{"line_number":215,"utf16_col":4},"end":{"line_number":215,"utf16_col":41}},"extent_utf16":{"start":{"line_number":215,"utf16_col":0},"end":{"line_number":407,"utf16_col":0}}},{"name":"`.github/workflows/deploy.yml`","fully_qualified_name":"`.github/workflows/deploy.yml`","kind":"section_3","ident_start":15743,"ident_end":15773,"extent_start":15739,"extent_end":17497,"ident_utf16":{"start":{"line_number":407,"utf16_col":4},"end":{"line_number":407,"utf16_col":34}},"extent_utf16":{"start":{"line_number":407,"utf16_col":0},"end":{"line_number":479,"utf16_col":0}}},{"name":"`.github/workflows/unlock-on-merge.yml`","fully_qualified_name":"`.github/workflows/unlock-on-merge.yml`","kind":"section_3","ident_start":17501,"ident_end":17540,"extent_start":17497,"extent_end":17957,"ident_utf16":{"start":{"line_number":479,"utf16_col":4},"end":{"line_number":479,"utf16_col":43}},"extent_utf16":{"start":{"line_number":479,"utf16_col":0},"end":{"line_number":505,"utf16_col":0}}},{"name":"`.github/deployment_message.md`","fully_qualified_name":"`.github/deployment_message.md`","kind":"section_3","ident_start":17961,"ident_end":17992,"extent_start":17957,"extent_end":18529,"ident_utf16":{"start":{"line_number":505,"utf16_col":4},"end":{"line_number":505,"utf16_col":35}},"extent_utf16":{"start":{"line_number":505,"utf16_col":0},"end":{"line_number":521,"utf16_col":0}}},{"name":"Heroku","fully_qualified_name":"Heroku","kind":"section_2","ident_start":18532,"ident_end":18538,"extent_start":18529,"extent_end":20159,"ident_utf16":{"start":{"line_number":521,"utf16_col":3},"end":{"line_number":521,"utf16_col":9}},"extent_utf16":{"start":{"line_number":521,"utf16_col":0},"end":{"line_number":575,"utf16_col":0}}},{"name":"Railway","fully_qualified_name":"Railway","kind":"section_2","ident_start":20162,"ident_end":20169,"extent_start":20159,"extent_end":21782,"ident_utf16":{"start":{"line_number":575,"utf16_col":3},"end":{"line_number":575,"utf16_col":10}},"extent_utf16":{"start":{"line_number":575,"utf16_col":0},"end":{"line_number":631,"utf16_col":0}}},{"name":"SSH","fully_qualified_name":"SSH","kind":"section_2","ident_start":21785,"ident_end":21788,"extent_start":21782,"extent_end":23701,"ident_utf16":{"start":{"line_number":631,"utf16_col":3},"end":{"line_number":631,"utf16_col":6}},"extent_utf16":{"start":{"line_number":631,"utf16_col":0},"end":{"line_number":689,"utf16_col":0}}},{"name":"Cloudflare Pages","fully_qualified_name":"Cloudflare Pages","kind":"section_2","ident_start":23704,"ident_end":23720,"extent_start":23701,"extent_end":26940,"ident_utf16":{"start":{"line_number":689,"utf16_col":3},"end":{"line_number":689,"utf16_col":19}},"extent_utf16":{"start":{"line_number":689,"utf16_col":0},"end":{"line_number":772,"utf16_col":0}}},{"name":"Cloudflare Workers","fully_qualified_name":"Cloudflare Workers","kind":"section_2","ident_start":26943,"ident_end":26961,"extent_start":26940,"extent_end":29737,"ident_utf16":{"start":{"line_number":772,"utf16_col":3},"end":{"line_number":772,"utf16_col":21}},"extent_utf16":{"start":{"line_number":772,"utf16_col":0},"end":{"line_number":843,"utf16_col":0}}},{"name":"Multiple Jobs","fully_qualified_name":"Multiple Jobs","kind":"section_2","ident_start":29740,"ident_end":29753,"extent_start":29737,"extent_end":38791,"ident_utf16":{"start":{"line_number":843,"utf16_col":3},"end":{"line_number":843,"utf16_col":16}},"extent_utf16":{"start":{"line_number":843,"utf16_col":0},"end":{"line_number":1045,"utf16_col":0}}},{"name":"Multiple Jobs with GitHub Pages and Hugo","fully_qualified_name":"Multiple Jobs with GitHub Pages and Hugo","kind":"section_2","ident_start":38794,"ident_end":38834,"extent_start":38791,"extent_end":50925,"ident_utf16":{"start":{"line_number":1045,"utf16_col":3},"end":{"line_number":1045,"utf16_col":43}},"extent_utf16":{"start":{"line_number":1045,"utf16_col":0},"end":{"line_number":1319,"utf16_col":0}}},{"name":"Multiple Jobs with GitHub Pages and Astro","fully_qualified_name":"Multiple Jobs with GitHub Pages and Astro","kind":"section_2","ident_start":50928,"ident_end":50969,"extent_start":50925,"extent_end":61681,"ident_utf16":{"start":{"line_number":1319,"utf16_col":3},"end":{"line_number":1319,"utf16_col":44}},"extent_utf16":{"start":{"line_number":1319,"utf16_col":0},"end":{"line_number":1560,"utf16_col":0}}},{"name":"Multiple Jobs with GitHub Environments","fully_qualified_name":"Multiple Jobs with GitHub Environments","kind":"section_2","ident_start":61684,"ident_end":61722,"extent_start":61681,"extent_end":75067,"ident_utf16":{"start":{"line_number":1560,"utf16_col":3},"end":{"line_number":1560,"utf16_col":41}},"extent_utf16":{"start":{"line_number":1560,"utf16_col":0},"end":{"line_number":1907,"utf16_col":0}}}]}},"codeViewLayoutRoute":{"repo":{"id":486614111,"defaultBranch":"main","name":"branch-deploy","ownerLogin":"github","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2022-04-28T13:51:25.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/9919?v=4","public":true,"private":false,"isOrgOwned":true,"isArchived":false},"currentUser":null,"uploadToken":"KDwBs81Z9L4x1mzk2FGbyYHeRS5SMAy5EYTV2z34IBLeIxjYevRELoWg2hnfXrn-jYw_VjyvjEnZyLZKXW8QoQ","allShortcutsEnabled":false,"treeExpanded":true,"path":"docs/examples.md","symbolsExpanded":false,"refInfo":{"name":"main","listCacheKey":"v0:1790650997.0","canEdit":false,"currentOid":"97edad089bbbe0c0ad13db7bf9ac085eaa47e255"},"helpUrl":"https://docs.github.com","githubDevUrl":null},"codeViewFileTreeLayoutRoute":{"fileTree":{"docs":{"items":[{"name":"assets","path":"docs/assets","contentType":"directory"},{"name":"branch-rulesets.md","path":"docs/branch-rulesets.md","contentType":"file"},{"name":"checks.md","path":"docs/checks.md","contentType":"file"},{"name":"custom-deployment-messages.md","path":"docs/custom-deployment-messages.md","contentType":"file"},{"name":"deploying-commit-SHAs.md","path":"docs/deploying-commit-SHAs.md","contentType":"file"},{"name":"deployment-confirmation.md","path":"docs/deployment-confirmation.md","contentType":"file"},{"name":"deployment-payload.md","path":"docs/deployment-payload.md","contentType":"file"},{"name":"deprecated.md","path":"docs/deprecated.md","contentType":"file"},{"name":"enforced-deployment-order.md","path":"docs/enforced-deployment-order.md","contentType":"file"},{"name":"examples.md","path":"docs/examples.md","contentType":"file"},{"name":"hubot-style-deployment-locks.md","path":"docs/hubot-style-deployment-locks.md","contentType":"file"},{"name":"locks.md","path":"docs/locks.md","contentType":"file"},{"name":"maintainer-guide.md","path":"docs/maintainer-guide.md","contentType":"file"},{"name":"merge-commit-strategy.md","path":"docs/merge-commit-strategy.md","contentType":"file"},{"name":"naked-commands.md","path":"docs/naked-commands.md","contentType":"file"},{"name":"outdated_mode.md","path":"docs/outdated_mode.md","contentType":"file"},{"name":"parameters.md","path":"docs/parameters.md","contentType":"file"},{"name":"sha-deployments.md","path":"docs/sha-deployments.md","contentType":"file"},{"name":"trusted-checkouts.md","path":"docs/trusted-checkouts.md","contentType":"file"},{"name":"unlock-on-merge.md","path":"docs/unlock-on-merge.md","contentType":"file"},{"name":"usage.md","path":"docs/usage.md","contentType":"file"},{"name":"v11-to-v12-upgrade-guide.md","path":"docs/v11-to-v12-upgrade-guide.md","contentType":"file"}],"totalCount":22},"":{"items":[{"name":".github","path":".github","contentType":"directory"},{"name":"__tests__","path":"__tests__","contentType":"directory"},{"name":"badges","path":"badges","contentType":"directory"},{"name":"dist","path":"dist","contentType":"directory"},{"name":"docs","path":"docs","contentType":"directory"},{"name":"events","path":"events","contentType":"directory"},{"name":"script","path":"script","contentType":"directory"},{"name":"src","path":"src","contentType":"directory"},{"name":"tools","path":"tools","contentType":"directory"},{"name":".gitattributes","path":".gitattributes","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".node-version","path":".node-version","contentType":"file"},{"name":".npmrc","path":".npmrc","contentType":"file"},{"name":".prettierignore","path":".prettierignore","contentType":"file"},{"name":".prettierrc.json","path":".prettierrc.json","contentType":"file"},{"name":"AGENTS.md","path":"AGENTS.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"action.yml","path":"action.yml","contentType":"file"},{"name":"package-lock.json","path":"package-lock.json","contentType":"file"},{"name":"package.json","path":"package.json","contentType":"file"},{"name":"tsconfig.json","path":"tsconfig.json","contentType":"file"},{"name":"tsconfig.runtime.json","path":"tsconfig.runtime.json","contentType":"file"}],"totalCount":24}},"fileTreeProcessingTime":13.609426000000001,"foldersToFetch":[]},"codeViewBlobLayoutRoute":{"codeLineWrapEnabled":false,"refInfo":{"name":"main","listCacheKey":"v0:1790650997.0","canEdit":false,"refType":"branch","currentOid":"97edad089bbbe0c0ad13db7bf9ac085eaa47e255","canEditOnDefaultBranch":false,"fileExistsOnDefault":true},"path":"docs/examples.md","blob":{"copilotSWEAgentEnabled":false,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/github/branch-deploy/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"examples.md","displayUrl":"https://github.com/github/branch-deploy/blob/main/docs/examples.md?raw=true","headerInfo":{"blobSize":"73.3 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"6d889b3","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fgithub%2Fbranch-deploy%2Fblob%2Fmain%2Fdocs%2Fexamples.md","isCSV":false,"isRichtext":true,"lineInfo":{"truncatedLoc":"1907","truncatedSloc":"1600"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"isIssueTemplate":false,"isDiscussionTemplate":false,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/github/branch-deploy/blob/main/docs/examples.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/github/branch-deploy/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/github/branch-deploy/raw/refs/heads/main/docs/examples.md","renderImageOrRaw":false,"shortPath":null,"symbolsEnabled":true,"tabSize":4,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null},"copilotInfo":null,"copilotAccessAllowed":false,"copilotSpacesEnabled":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true},"codeViewBlobLayoutRoute.StyledBlob":{"rawLines":["# Examples","","This section contains real world and common examples of how you could use this Action","","\u003e Note: In all examples, we will be using `uses: github/branch-deploy@vX.X.X`. Replace `X.X.X` with the [latest version](https://github.com/marketplace/actions/branch-deploy) of this Action","","## Table of Contents","","Quick links below to jump to a specific branch-deploy example:","","- [Examples](#examples)","  - [Table of Contents](#table-of-contents)","  - [Simple Example](#simple-example)","  - [Terraform](#terraform)","  - [Terraform with Trusted Checkouts](#terraform-with-trusted-checkouts)","  - [Heroku](#heroku)","  - [Railway](#railway)","  - [SSH](#ssh)","  - [Cloudflare Pages](#cloudflare-pages)","  - [Cloudflare Workers](#cloudflare-workers)","  - [Multiple Jobs](#multiple-jobs)","  - [Multiple Jobs with GitHub Pages and Hugo](#multiple-jobs-with-github-pages-and-hugo)","  - [Multiple Jobs with GitHub Pages and Astro](#multiple-jobs-with-github-pages-and-astro)","  - [Multiple Jobs with GitHub Environments](#multiple-jobs-with-github-environments)","","## Simple Example","","This is the simplest possible example of how you could use the branch-deploy Action for reference","","- `.noop` will run the noop deploy step only (you can configure noop deployments however you like, this is just an example)","- `.deploy` will deploy the current branch via the deploy step only (you can configure deployments however you like, this is just an example)","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","# Permissions needed for reacting and adding comments for IssueOps commands","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  deploy:","    name: deploy","    runs-on: ubuntu-latest","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","","    steps:","      # The branch-deploy Action","      - name: branch-deploy","        id: branch-deploy","        uses: github/branch-deploy@vX.X.X","","        # If the branch-deploy Action was triggered, checkout our branch","      - uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          persist-credentials: false","","        # If the branch-deploy Action was triggered, run the noop deployment (i.e. '.noop')","      - name: noop deploy","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop == 'true' }}","        run: \u003cdo-your-noop-deployment\u003e # this could be anything you want","","        # If the branch-deploy Action was triggered, run the real deployment (i.e. '.deploy')","      - name: deploy","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' }}","        run: \u003cdo-your-deployment\u003e # this could be anything you want","```","","## Terraform","","This example shows how you could use this Action with [Terraform](https://www.terraform.io/)","","- `.noop` triggers a Terraform plan","- `.deploy` triggers a Terraform apply","","All deployment results get posted as a comment in the branch deploy output on your pull request","","\u003e A live example can be found [here](https://github.com/the-hideout/cloudflare/blob/3f3adedb729b9aba0cc324a161ad8ddd6f56141b/.github/workflows/branch-deploy.yml)","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","# The working directory where our Terraform files are located","env:","  WORKING_DIR: terraform/","","# Permissions needed for reacting and adding comments for IssueOps commands","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  deploy:","    name: deploy","    runs-on: ubuntu-latest","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","    environment: production-secrets # the locked down environment we pull secrets from","    defaults:","      run:","        working-directory: ${{ env.WORKING_DIR }} # the directory we use where all our TF files are stored","","    steps:","      # The branch-deploy Action","      - name: branch-deploy","        id: branch-deploy","        uses: github/branch-deploy@vX.X.X","","        # If the branch-deploy Action was triggered, checkout our branch","      - name: Checkout","        if: steps.branch-deploy.outputs.continue == 'true'","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          persist-credentials: false","","        # Setup Terraform on our Actions runner","      - uses: hashicorp/setup-terraform@ed3a0531877aca392eb870f440d9ae7aba83a6bd # pin@v1","        if: steps.branch-deploy.outputs.continue == 'true'","        with:","          terraform_version: 1.1.7 # use the version of Terraform your project uses here","          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}","","        # Run Terraform init in our working directory","      - name: Terraform init","        if: steps.branch-deploy.outputs.continue == 'true'","        run: terraform init","","        # If '.noop' was used, run a Terraform plan","      - name: Terraform plan","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop == 'true' }}","        id: plan","        run: terraform plan -no-color","        continue-on-error: true # continue on error as we will handle errors later on","","        # If '.deploy' was used, run a Terraform apply","      - name: Terraform apply","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' }}","        id: apply","        run: terraform apply -no-color -auto-approve","        continue-on-error: true # continue on error as we will handle errors later on","","        # This step writes the TF plan/apply output to $GITHUB_ENV which the branch-deploy Action will read from and post as a comment on the pull request","      - name: Terraform plan output","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop == 'true' }}","        env:","          TF_STDOUT: ${{ steps.plan.outputs.stdout }}","        run: |","          delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"","          while printf '%s\\n' \"$TF_STDOUT\" | grep -Fxq \"$delimiter\"; do","            delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"","          done","          {","            printf 'DEPLOY_MESSAGE\u003c\u003c%s\\n' \"$delimiter\"","            printf '%s\\n' '```terraform'","            printf '%s\\n' \"$TF_STDOUT\"","            printf '%s\\n' '```'","            printf '%s\\n' \"$delimiter\"","          } \u003e\u003e \"$GITHUB_ENV\"","","      - name: Terraform apply output","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' }}","        env:","          TF_STDOUT: ${{ steps.apply.outputs.stdout }}","        run: |","          delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"","          while printf '%s\\n' \"$TF_STDOUT\" | grep -Fxq \"$delimiter\"; do","            delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"","          done","          {","            printf 'DEPLOY_MESSAGE\u003c\u003c%s\\n' \"$delimiter\"","            printf '%s\\n' '```terraform'","            printf '%s\\n' \"$TF_STDOUT\"","            printf '%s\\n' '```'","            printf '%s\\n' \"$delimiter\"","          } \u003e\u003e \"$GITHUB_ENV\"","","        # Here we handle any errors that might have occurred during the Terraform plan/apply and exit accordingly","      - name: Check Terraform plan output","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop == 'true' \u0026\u0026 steps.plan.outcome == 'failure' }}","        run: exit 1","      - name: Check Terraform apply output","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' \u0026\u0026 steps.apply.outcome == 'failure' }}","        run: exit 1","```","","## Terraform with Trusted Checkouts","","This example shows a hardened Terraform setup that separates trusted deployment","helper code from the working pull request code selected by branch-deploy.","","- `.noop` runs `terraform plan` from the exact working commit SHA selected by branch-deploy","- `.deploy` runs `terraform apply` from that same working commit SHA","- the deployment message template is fetched by Branch Deploy at the exact trusted workflow SHA","- Terraform output is captured in `RUNNER_TEMP` and exported through `DEPLOY_MESSAGE`","- merge deploy mode avoids redeploying a default-branch commit only when the newest relevant Branch Deploy deployment is active and has the same commit tree","- unlock-on-merge mode cleans up sticky locks after the pull request merges","","For the general security model behind this pattern, see the","[trusted checkout hardening guide](trusted-checkouts.md).","","### `.github/workflows/branch-deploy.yml`","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","env:","  TF_IN_AUTOMATION: \"true\"","","jobs:","  branch-deploy:","    if:","      ${{ github.event.issue.pull_request \u0026\u0026","      (startsWith(github.event.comment.body, '.deploy') ||","      startsWith(github.event.comment.body, '.noop') ||","      startsWith(github.event.comment.body, '.lock') ||","      startsWith(github.event.comment.body, '.help') ||","      startsWith(github.event.comment.body, '.wcid') ||","      startsWith(github.event.comment.body, '.unlock')) }}","    runs-on: ubuntu-latest","    environment:","      name: production","      deployment: false","    concurrency:","      group: ${{ (startsWith(github.event.comment.body, '.deploy') || startsWith(github.event.comment.body, '.noop')) \u0026\u0026 'terraform-production' || format('branch-deploy-support-{0}', github.run_id) }}","      cancel-in-progress: false","      queue: max","","    steps:","      - name: branch-deploy","        id: branch-deploy","        uses: github/branch-deploy@vX.X.X","        with:","          trigger: \".deploy\"","          sticky_locks: true","          deployment_confirmation: true","          deploy_message_path: .github/deployment_message.md","          allow_forks: false","","      - name: derive working checkout path","        id: working-path","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          DEPLOY_SHA: ${{ steps.branch-deploy.outputs.sha }}","        run: |","          set -euo pipefail","          echo \"DEPLOY_SHA=${DEPLOY_SHA}\"","","          if [[ ! \"${DEPLOY_SHA}\" =~ ^[0-9a-fA-F]{40}([0-9a-fA-F]{24})?$ ]]; then","            echo \"invalid branch-deploy sha output: ${DEPLOY_SHA}\" \u003e\u00262","            exit 1","          fi","","          working_dir=\"deployment-${DEPLOY_SHA}\"","","          echo \"working_dir=${working_dir}\" \u003e\u003e \"${GITHUB_OUTPUT}\"","          echo \"working checkout directory: ${working_dir}\"","","      - name: checkout working deployment sha","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          path: ${{ steps.working-path.outputs.working_dir }}","          fetch-depth: 1","          persist-credentials: false","","      - name: verify checkout provenance","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          WORKING_DIR: ${{ steps.working-path.outputs.working_dir }}","          WORKING_SHA: ${{ steps.branch-deploy.outputs.sha }}","        run: |","          set -euo pipefail","","          working_head=\"$(git -C \"${WORKING_DIR}\" rev-parse HEAD)\"","","          if [[ \"${working_head}\" != \"${WORKING_SHA}\" ]]; then","            echo \"working checkout HEAD mismatch: expected ${WORKING_SHA}, got ${working_head}\" \u003e\u00262","            exit 1","          fi","","          echo \"working checkout: ${WORKING_DIR}@${working_head}\"","","      - name: prepare terraform output path","        id: terraform-output","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        run: |","          set -euo pipefail","","          output_dir=\"$(mktemp -d \"${RUNNER_TEMP}/branch-deploy-output.XXXXXX\")\"","          output_path=\"${output_dir}/terraform-output.txt\"","          : \u003e \"${output_path}\"","","          if [[ -L \"${output_path}\" || ! -f \"${output_path}\" ]]; then","            echo \"terraform output path is not a regular file: ${output_path}\" \u003e\u00262","            exit 1","          fi","","          echo \"path=${output_path}\" \u003e\u003e \"${GITHUB_OUTPUT}\"","          echo \"terraform output path: ${output_path}\"","","      - name: read terraform version","        id: terraform-version","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform","        run: echo \"version=$(cat .terraform-version)\" \u003e\u003e \"$GITHUB_OUTPUT\"","","      - name: setup terraform","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        uses: hashicorp/setup-terraform@v4","        with:","          terraform_version: ${{ steps.terraform-version.outputs.version }}","","      - name: terraform init","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform","        env:","          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}","        run: terraform init","","      - name: terraform plan","        id: plan","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop == 'true' }}","        continue-on-error: true","        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform","        env:","          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}","          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}","        run: |","          set -o pipefail","          terraform plan -no-color -compact-warnings | tee \"$TERRAFORM_OUTPUT_PATH\"","","      - name: terraform apply","        id: apply","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' }}","        continue-on-error: true","        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform","        env:","          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}","          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}","        run: |","          set -o pipefail","          terraform apply -auto-approve -no-color -compact-warnings | tee \"$TERRAFORM_OUTPUT_PATH\"","","      - name: verify terraform output capture","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}","        run: |","          set -euo pipefail","","          if [[ -L \"${TERRAFORM_OUTPUT_PATH}\" || ! -f \"${TERRAFORM_OUTPUT_PATH}\" ]]; then","            echo \"terraform output path is not a regular file: ${TERRAFORM_OUTPUT_PATH}\" \u003e\u00262","            exit 1","          fi","","      - name: export deploy message","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          RESULTS_PATH: ${{ steps.terraform-output.outputs.path }}","        run: |","          set -euo pipefail","          delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"","          while grep -Fxq \"${delimiter}\" \"${RESULTS_PATH}\"; do","            delimiter=\"branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \\n')\"","          done","          {","            printf 'DEPLOY_MESSAGE\u003c\u003c%s\\n' \"${delimiter}\"","            cat \"${RESULTS_PATH}\"","            printf '\\n%s\\n' \"${delimiter}\"","          } \u003e\u003e \"${GITHUB_ENV}\"","","      - name: check terraform plan","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop == 'true' \u0026\u0026 steps.plan.outcome == 'failure' }}","        run: exit 1","","      - name: check terraform apply","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' \u0026\u0026 steps.apply.outcome == 'failure' }}","        run: exit 1","```","","### `.github/workflows/deploy.yml`","","```yaml","name: deploy","","on:","  push:","    branches: [\"main\"]","","permissions:","  contents: read","  deployments: write","","jobs:","  deployment-check:","    runs-on: ubuntu-latest","    outputs:","      continue: ${{ steps.deployment-check.outputs.continue }}","      sha: ${{ steps.deployment-check.outputs.sha }}","","    steps:","      - name: deployment check","        id: deployment-check","        uses: github/branch-deploy@vX.X.X","        with:","          merge_deploy_mode: true","          environment: production","","  deploy:","    if: ${{ needs.deployment-check.outputs.continue == 'true' }}","    needs: deployment-check","    runs-on: ubuntu-latest","    concurrency:","      group: terraform-production","      cancel-in-progress: false","      queue: max","    environment: production","    defaults:","      run:","        working-directory: terraform/","    env:","      TF_IN_AUTOMATION: \"true\"","","    steps:","      - name: checkout","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ needs.deployment-check.outputs.sha }}","          fetch-depth: 1","          persist-credentials: false","","      - name: read terraform version","        id: terraform-version","        working-directory: .","        run: echo \"version=$(cat terraform/.terraform-version)\" \u003e\u003e \"$GITHUB_OUTPUT\"","","      - name: setup terraform","        uses: hashicorp/setup-terraform@v4","        with:","          terraform_version: ${{ steps.terraform-version.outputs.version }}","","      - name: terraform init","        env:","          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}","        run: terraform init","","      - name: terraform apply","        env:","          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}","        run: terraform apply -auto-approve -no-color -compact-warnings","```","","### `.github/workflows/unlock-on-merge.yml`","","```yaml","name: Unlock On Merge","","on:","  pull_request:","    types: [closed]","","permissions:","  contents: write","","jobs:","  unlock-on-merge:","    runs-on: ubuntu-latest","    if: github.event.pull_request.merged == true","","    steps:","      - name: unlock on merge","        id: unlock-on-merge","        uses: github/branch-deploy@vX.X.X","        with:","          unlock_on_merge_mode: true","          environment_targets: production","```","","### `.github/deployment_message.md`","","````markdown","### Deployment Results {{ \":white_check_mark:\" if status === \"success\" else \":x:\" }}","","{% if status === \"success\" %}**{{ actor }}** successfully **{{ \"noop\" if noop else \"branch\" }}** deployed branch `{{ ref }}` to **{{ environment }}**{% endif %}{% if status === \"failure\" %}**{{ actor }}** your **{{ \"noop\" if noop else \"branch\" }}** deployment of `{{ ref }}` failed to deploy to the **{{ environment }}** environment{% endif %}","","\u003cdetails\u003e\u003csummary\u003eShow Results\u003c/summary\u003e","","```terraform","{{ results }}","```","","\u003c/details\u003e","````","","## Heroku","","This example shows how you could use this Action with [Heroku](https://heroku.com)","","- `.noop` has no effect here (but you could change that)","- `.deploy` takes your current branch and deploys it to Heroku","","\u003e A live example can be found [here](https://github.com/the-hideout/stash/blob/aef5a5f16b4fa6946d2eba107e7b92c5f6583c0d/.github/workflows/branch-deploy.yml)","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  deploy:","    name: deploy","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","    runs-on: ubuntu-latest","    environment: production-secrets # the locked down environment we pull secrets from","","    steps:","      # The branch-deploy Action","      - name: branch-deploy","        id: branch-deploy","        uses: github/branch-deploy@vX.X.X","","        # If the branch-deploy Action was triggered, checkout our branch","      - name: Checkout","        if: steps.branch-deploy.outputs.continue == 'true'","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          persist-credentials: false","","        # Deploy our branch to Heroku","      - name: Deploy to Heroku","        if: steps.branch-deploy.outputs.continue == 'true'","        uses: AkhileshNS/heroku-deploy@79ef2ae4ff9b897010907016b268fd0f88561820 # pin@v3.12.12","        with:","          heroku_app_name: \u003cyour-heroku-app-name-here\u003e","          heroku_email: ${{ secrets.HEROKU_EMAIL }}","          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}","```","","## Railway","","This example shows how you could use this Action with [Railway](https://railway.app)","","- `.noop` has no effect here (but you could change that)","- `.deploy` takes your current branch and deploys it to Railway","","\u003e A live example can be found [here](https://github.com/the-hideout/stash/blob/ee8af01919f368f35dede3c93f703fd239dbac3c/.github/workflows/branch-deploy.yml) that has some slight modifications to the example below","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  deploy:","    name: deploy","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","    runs-on: ubuntu-latest","    environment: production-secrets # the locked down environment we pull secrets from","","    steps:","      # The branch-deploy Action","      - name: branch-deploy","        id: branch-deploy","        uses: github/branch-deploy@vX.X.X","","        # If the branch-deploy Action was triggered, checkout our branch","      - name: Checkout","        if: steps.branch-deploy.outputs.continue == 'true'","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          persist-credentials: false","","        # Install the Railway CLI through npm","      - name: Install Railway","        run: npm i -g @railway/cli","","        # Deploy our branch to Railway","      - name: Deploy to Railway","        if: steps.branch-deploy.outputs.continue == 'true'","        env:","          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}","        run: railway up","```","","## SSH","","This example shows how you could use this Action with SSH","","You can define any commands you want to be run in your SSH Action and they would be gated by the branch-deploy Action.","","- `.noop` has no effect here (but you could change that)","- `.deploy` runs the SSH action with your branch","","\u003e A live example can be found [here](https://github.com/the-hideout/cache/blob/6ee6ee2a69104f165c9f20df6e4e5cbb337b7c54/.github/workflows/branch-deploy.yml)","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","# Permissions needed for reacting and adding comments for IssueOps commands","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  deploy:","    environment: production-secrets # the locked down environment we pull secrets from","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","    runs-on: ubuntu-latest","","    steps:","      # The branch-deploy Action","      - uses: github/branch-deploy@vX.X.X","        id: branch-deploy","","        # If the branch-deploy Action was triggered, checkout our branch","      - name: Checkout","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          persist-credentials: false","","        # Deploy our branch via SSH remote commands","      - name: SSH Remote Deploy","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' }}","        uses: appleboy/ssh-action@4a03da89e5c43da56e502053be4bbcb293411883 # pin@v0.1.6","        with:","          host: ${{ secrets.SSH_HOST }}","          username: ${{ secrets.SSH_USERNAME }}","          key: ${{ secrets.SSH_KEY }}","          port: ${{ secrets.SSH_PORT }}","          script_stop: true","          script: \u003crun-some-ssh-commands-here\u003e # this could be whatever you want","```","","## Cloudflare Pages","","This example shows how you could use this Action with [Cloudflare Pages](https://pages.cloudflare.com/)","","- `.deploy to development` deploys your branch to the development environment","- `.deploy` deploys your branch to the production environment","","\u003e A live example can be found [here](https://github.com/the-hideout/tarkov-dev/blob/b4417dfeb903985b83a24096b2e1ba2a22f39ddd/.github/workflows/branch-deploy.yml)","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","# Permissions needed for reacting and adding comments for IssueOps commands","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  deploy:","    environment: secrets # the locked down environment we pull secrets from","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","    runs-on: ubuntu-latest","","    steps:","      # The branch-deploy Action","      - uses: github/branch-deploy@vX.X.X","        id: branch-deploy","","        # If the branch-deploy Action was triggered, checkout our branch","      - name: Checkout","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          persist-credentials: false","","        # setup node","      - uses: actions/setup-node@v4","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        with:","          node-version: '18'","          cache: 'npm'","","        # Install the npm dependencies to build our cloudflare pages site","      - name: Install","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        run: npm ci","","        # Build our cloudflare pages site","      - name: Build","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        run: npm run build","","        # If '.deploy to development' was used, branch deploy to the development environment","      - name: deploy - dev","        id: dev-deploy","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' \u0026\u0026 steps.branch-deploy.outputs.environment == 'development' }}","        uses: cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 # pin@3.3.1","        with:","          wranglerVersion: '2.13.0' # this can be any version of wrangler you want","          apiToken: ${{ secrets.CF_API_TOKEN }}","          accountId: ${{ secrets.CF_ACCOUNT_ID }}","          command: pages publish build/ --project-name=\u003cyour-cloudflare-project-name\u003e --branch=preview","","        # If '.deploy' was used, branch deploy to the production environment","      - name: deploy - prod","        id: prod-deploy","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026 steps.branch-deploy.outputs.noop != 'true' \u0026\u0026 steps.branch-deploy.outputs.environment == 'production' }}","        uses: cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 # pin@3.3.1","        with:","          wranglerVersion: '2.13.0' # this can be any version of wrangler you want","          apiToken: ${{ secrets.CF_API_TOKEN }}","          accountId: ${{ secrets.CF_ACCOUNT_ID }}","          command: pages publish build/ --project-name=\u003cyour-cloudflare-project-name\u003e --branch=main","```","","## Cloudflare Workers","","This example shows how you could use this Action with [Cloudflare Workers](https://workers.cloudflare.com/)","","- `.deploy to development` deploys your branch to the development environment (if you have one with your Cloudflare workers)","- `.deploy` deploys your branch to the production environment","","\u003e A live example can be found [here](https://github.com/the-hideout/tarkov-api/blob/1677543951d5f2a848c2650eb3400178b8f9a55b/.github/workflows/branch-deploy.yml)","","```yaml","name: branch-deploy","","on:","  issue_comment:","    types: [created]","","# Permissions needed for reacting and adding comments for IssueOps commands","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  deploy:","    environment: secrets # the locked down environment we pull secrets from","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","    runs-on: ubuntu-latest","","    steps:","      # The branch-deploy Action","      - uses: github/branch-deploy@vX.X.X","        id: branch-deploy","","        # If the branch-deploy Action was triggered, checkout our branch","      - name: Checkout","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ steps.branch-deploy.outputs.sha }}","          persist-credentials: false","","        # Install the npm dependencies for your cloudflare workers project","        # Most importantly, we need to install @cloudflare/wrangler","      - name: Install dependencies","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        run: npm ci","","        # If '.deploy to development' was used, branch deploy to the development environment","      - name: Publish - Development","        if: ${{ steps.branch-deploy.outputs.environment == 'development' \u0026\u0026","          steps.branch-deploy.outputs.noop != 'true' \u0026\u0026","          steps.branch-deploy.outputs.continue == 'true' }}","        uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # pin@2.0.0","        with:","          wranglerVersion: '2.17.0' # this can be any version of wrangler you want","          apiToken: ${{ secrets.CF_API_TOKEN }}","          environment: 'development' # here we use development","","        # If '.deploy' was used, branch deploy to the production environment","      - name: Publish - Production","        if: ${{ steps.branch-deploy.outputs.continue == 'true' \u0026\u0026","          steps.branch-deploy.outputs.noop != 'true' \u0026\u0026","          steps.branch-deploy.outputs.environment == 'production' }}","        uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # pin@2.0.0","        with:","          wranglerVersion: '2.17.0' # this can be any version of wrangler you want","          apiToken: ${{ secrets.CF_API_TOKEN }}","```","","## Multiple Jobs","","If you need a complex deployment workflow, you can complete the deployment manually in a separate job. With `skip_completing: true`, your workflow owns final deployment statuses, comments, reactions, labels, and non-sticky lock cleanup. See [here](https://github.com/github/branch-deploy/blob/main/README.md#manual-deployment-control) for more details.","","\u003e This is a more advanced example","","```yaml","name: deploy","","on:","  issue_comment:","    types: [created]","","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","jobs:","  trigger:","    if: ${{ github.event.issue.pull_request }} # only run on pull request comments","    runs-on: ubuntu-latest","    outputs:","      continue: ${{ steps.branch-deploy.outputs.continue }}","      noop: ${{ steps.branch-deploy.outputs.noop }}","      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}","      environment: ${{ steps.branch-deploy.outputs.environment }}","      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}","      sha: ${{ steps.branch-deploy.outputs.sha }}","      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}","      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}","      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}","","    steps:","      - uses: github/branch-deploy@vX.X.X","        id: branch-deploy","        with:","          trigger: \".deploy\"","          skip_completing: true # we will complete the deployment manually","","      - name: Capture deployment lock","        id: capture-lock","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","        run: |","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u003e/dev/null)\"; then","            printf 'sha=%s\\n' \"$lock_ref_sha\" \u003e\u003e \"$GITHUB_OUTPUT\"","          else","            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"","          fi","","  deploy:","    needs: trigger","    if: ${{ needs.trigger.outputs.continue == 'true' \u0026\u0026 needs.trigger.outputs.noop != 'true' }}","    runs-on: ubuntu-latest","","    steps:","      # checkout the project's repository based on the commit SHA provided by the branch-deploy step","      - name: checkout","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ needs.trigger.outputs.sha }}","          persist-credentials: false","","      # You will do your own deployment here","      - name: fake regular deploy","        run: echo \"I am doing a fake regular deploy\"","","  # update the deployment result - manually complete the deployment that was created by the branch-deploy action","  result:","    needs: [trigger, deploy]","    runs-on: ubuntu-latest","    # run even on failures but only if the trigger job set continue to true","    if: ${{ always() \u0026\u0026 needs.trigger.outputs.continue == 'true' }}","","    steps:","      # if a previous step failed, set a variable to use as the deployment status","      - name: set deployment status","        id: deploy-status","        if: ${{ needs.trigger.result == 'failure' || needs.deploy.result == 'failure' }}","        run: |","          echo \"DEPLOY_STATUS=failure\" \u003e\u003e $GITHUB_OUTPUT","","      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action","      - name: Create a deployment status","        env:","          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}","          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}","        run: |","          if [ -z \"${DEPLOY_STATUS}\" ]; then","            DEPLOY_STATUS=\"success\"","          fi","","          gh api \\","            --method POST \\","            \"repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\" \\","            -f environment=\"${ENVIRONMENT}\" \\","            -f state=\"${DEPLOY_STATUS}\"","","      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action","      - name: Remove a non-sticky lock","        env:","          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}","          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          ISSUE_NUMBER: ${{ github.event.issue.number }}","          LOCK_ACTOR: ${{ github.actor }}","          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}","        run: |","          if [ -z \"${LOCK_REF_SHA}\" ]; then","            echo \"No captured deployment lock remains\"","            exit 0","          fi","","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"","          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"","","          if ! printf '%s' \"$lock_contents\" | jq -e \\","            --arg actor \"$LOCK_ACTOR\" \\","            --arg environment \"$ENVIRONMENT\" \\","            --arg link \"$lock_link\" \\","            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u003e/dev/null; then","            echo \"The captured deployment lock is sticky or belongs to another deployment\"","            exit 0","          fi","","          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"","          if gh api graphql \\","            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\","            -f repository=\"$repository_id\" \\","            -f name=\"refs/heads/${lock_branch}\" \\","            -f before=\"$LOCK_REF_SHA\" \u003e/dev/null; then","            echo \"Removed the original deployment lock\"","          else","            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"","          fi","","      # remove the default 'eyes' reaction from the comment that triggered the deployment","      # this reaction is added by the branch-deploy action by default","      - name: remove eyes reaction","        env:","          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}","        run: |","          if [ -n \"${INITIAL_REACTION_ID}\" ]; then","            gh api \\","              --method DELETE \\","              \"repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"","          fi","","      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment","      - name: rocket reaction","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}","        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7","        with:","          comment-id: ${{ needs.trigger.outputs.comment_id }}","          reactions: rocket","","      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment","      - name: failure reaction","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}","        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7","        with:","          comment-id: ${{ needs.trigger.outputs.comment_id }}","          reactions: '-1'","","      # if the deployment was successful, add a 'success' comment","      - name: success comment","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}","        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1","        with:","          issue-number: ${{ github.event.issue.number }}","          body: |","            ### Deployment Results ✅","","            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**","","      # if the deployment was not successful, add a 'failure' comment","      - name: failure comment","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}","        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1","        with:","          issue-number: ${{ github.event.issue.number }}","          body: |","            ### Deployment Results ❌","","            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**","```","","## Multiple Jobs with GitHub Pages and Hugo","","A detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments. This example showcases building a static site with [hugo](https://gohugo.io/) and deploying it to [GitHub Pages](https://pages.github.com/).","","\u003e This live example can be found [here](https://github.com/GrantBirki/blog/blob/559b9be5cc3eac923be5d7923ec9a0b50429ced2/.github/workflows/branch-deploy.yml)","","```yaml","name: branch deploy","","# The workflow to execute on is comments that are newly created","on:","  issue_comment:","    types: [created]","","# Permissions needed for reacting and adding comments for IssueOps commands","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","","# set an environment variable for use in the jobs pointing to my blog","env:","  blog_url: https://test.example.com # \u003c--- CHANGE THIS TO YOUR BLOG URL","","jobs:","  # branch-deploy trigger job","  trigger:","    if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings","      ${{ github.event.issue.pull_request \u0026\u0026","      (contains(github.event.comment.body, '.deploy') ||","      contains(github.event.comment.body, '.lock') ||","      contains(github.event.comment.body, '.noop') ||","      contains(github.event.comment.body, '.help') ||","      contains(github.event.comment.body, '.wcid') ||","      contains(github.event.comment.body, '.unlock')) }}","    runs-on: ubuntu-latest","    outputs: # set outputs for use in downstream jobs","      continue: ${{ steps.branch-deploy.outputs.continue }}","      noop: ${{ steps.branch-deploy.outputs.noop }}","      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}","      environment: ${{ steps.branch-deploy.outputs.environment }}","      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}","      sha: ${{ steps.branch-deploy.outputs.sha }}","      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}","      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}","      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}","","    steps:","      # execute the branch-deploy action","      - uses: github/branch-deploy@vX.X.X","        id: branch-deploy","        with:","          trigger: '.deploy'","          environment: 'github-pages'","          production_environments: 'github-pages'","          skip_completing: true # we will complete the deployment manually in the 'result' job","          admins: 'false' # \u003c--- add your GitHub username here (if you want to use the admins feature)","","      - name: Capture deployment lock","        id: capture-lock","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","        run: |","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u003e/dev/null)\"; then","            printf 'sha=%s\\n' \"$lock_ref_sha\" \u003e\u003e \"$GITHUB_OUTPUT\"","          else","            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"","          fi","","  # build the github-pages site with hugo","  build:","    needs: trigger","    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true","    runs-on: ubuntu-latest","","    steps:","      # checkout the project's repository based on the commit SHA provided by the branch-deploy step","      - name: checkout","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ needs.trigger.outputs.sha }}","          persist-credentials: false","","      # read the hugo version from the .hugo-version file in this repository","      - name: set hugo version","        id: hugo-version","        run: |","          HUGO_VERSION=$(cat .hugo-version)","          echo \"HUGO_VERSION=${HUGO_VERSION}\" \u003e\u003e $GITHUB_OUTPUT","","      # install the hugo cli using the version detected in the previous step","      - name: install hugo cli","        env:","          HUGO_VERSION: ${{ steps.hugo-version.outputs.HUGO_VERSION }}","        run: |","          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.deb \\","          \u0026\u0026 sudo dpkg -i ${{ runner.temp }}/hugo.deb","","      # configure the GitHub Pages action","      - name: setup pages","        id: pages","        uses: actions/configure-pages@c5a3e1159e0cbdf0845eb8811bd39e39fc3099c2 # pin@v2.1.3","","      # build the site with hugo","      - name: build with hugo","        env:","          BASE_URL: ${{ steps.pages.outputs.base_url }}","        run: |","          hugo --gc --verbose \\","            --baseURL \"$BASE_URL\"","","      # this step is custom to my blog and adds a 'commit' version to the site","      - name: write build version","        run: echo ${GITHUB_SHA} \u003e ./public/version.txt","","      # upload the built site as an artifact for the deploy step","      - name: upload artifact","        uses: actions/upload-pages-artifact@253fd476ed429e83b7aae64a92a75b4ceb1a17cf # pin@v1.0.7","        with:","          path: ./public","","  # deploy to GitHub Pages","  deploy:","    needs: [trigger, build]","    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true","    environment:","      name: github-pages","      url: ${{ steps.deployment.outputs.page_url }}","    runs-on: ubuntu-latest","","    steps:","      # deploy the site to GitHub Pages","      - name: deploy","        id: deployment","        uses: actions/deploy-pages@20a4baa1095bad40ba7d6ca0d9abbc220b76603f # pin@v1.2.3","","  # update the deployment result - manually complete the deployment that was created by the branch-deploy action","  result:","    needs: [trigger, build, deploy]","    runs-on: ubuntu-latest","    # run even on failures but only if the trigger job set continue to true","    if: ${{ always() \u0026\u0026 needs.trigger.outputs.continue == 'true' }}","","    steps:","      # if a previous step failed, set a variable to use as the deployment status","      - name: set deployment status","        id: deploy-status","        if:","          ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||","          needs.deploy.result == 'failure' }}","        run: |","          echo \"DEPLOY_STATUS=failure\" \u003e\u003e $GITHUB_OUTPUT","","      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action","      - name: Create a deployment status","        env:","          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}","          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}","        run: |","          if [ -z \"${DEPLOY_STATUS}\" ]; then","            DEPLOY_STATUS=\"success\"","          fi","","          gh api \\","            --method POST \\","            \"repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\" \\","            -f environment=\"${ENVIRONMENT}\" \\","            -f state=\"${DEPLOY_STATUS}\"","","      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action","      - name: Remove a non-sticky lock","        env:","          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}","          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          ISSUE_NUMBER: ${{ github.event.issue.number }}","          LOCK_ACTOR: ${{ github.actor }}","          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}","        run: |","          if [ -z \"${LOCK_REF_SHA}\" ]; then","            echo \"No captured deployment lock remains\"","            exit 0","          fi","","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"","          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"","","          if ! printf '%s' \"$lock_contents\" | jq -e \\","            --arg actor \"$LOCK_ACTOR\" \\","            --arg environment \"$ENVIRONMENT\" \\","            --arg link \"$lock_link\" \\","            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u003e/dev/null; then","            echo \"The captured deployment lock is sticky or belongs to another deployment\"","            exit 0","          fi","","          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"","          if gh api graphql \\","            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\","            -f repository=\"$repository_id\" \\","            -f name=\"refs/heads/${lock_branch}\" \\","            -f before=\"$LOCK_REF_SHA\" \u003e/dev/null; then","            echo \"Removed the original deployment lock\"","          else","            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"","          fi","","      # remove the default 'eyes' reaction from the comment that triggered the deployment","      # this reaction is added by the branch-deploy action by default","      - name: remove eyes reaction","        env:","          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}","        run: |","          if [ -n \"${INITIAL_REACTION_ID}\" ]; then","            gh api \\","              --method DELETE \\","              \"repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"","          fi","","      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment","      - name: rocket reaction","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}","        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7","        with:","          comment-id: ${{ needs.trigger.outputs.comment_id }}","          reactions: rocket","","      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment","      - name: failure reaction","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}","        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7","        with:","          comment-id: ${{ needs.trigger.outputs.comment_id }}","          reactions: '-1'","","      # if the deployment was successful, add a 'success' comment","      - name: success comment","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}","        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1","        with:","          issue-number: ${{ github.event.issue.number }}","          body: |","            ### Deployment Results ✅","","            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**","","            \u003e [View Live Deployment](${{ env.blog_url }}) :link:","","      # if the deployment was not successful, add a 'failure' comment","      - name: failure comment","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}","        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1","        with:","          issue-number: ${{ github.event.issue.number }}","          body: |","            ### Deployment Results ❌","","            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**","```","","## Multiple Jobs with GitHub Pages and Astro","","A detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments - Using [Astro](https://astro.build) to create a static site and deploying to [GitHub Pages](https://pages.github.com/)","","\u003e A live example can be found [here](https://github.com/GrantBirki/astrowind-hard-fork/blob/be29d05cc0f3fe04e37ade9d38c653ed55c6cf53/.github/workflows/branch-deploy.yml)","","```yaml","name: branch deploy","","# The workflow to execute on is comments that are newly created","on:","  issue_comment:","    types: [created]","","# Permissions needed for reacting and adding comments for IssueOps commands","permissions:","  pull-requests: write","  deployments: write","  contents: write","  checks: read","  statuses: read","  pages: write","  id-token: write","","# set an environment variable for use in the jobs pointing the site_url","env:","  site_url: https://test.example.com # \u003c--- change this to your site url","","jobs:","  # branch-deploy trigger job","  trigger:","    if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings","      ${{ github.event.issue.pull_request \u0026\u0026","      (contains(github.event.comment.body, '.deploy') ||","      contains(github.event.comment.body, '.lock') ||","      contains(github.event.comment.body, '.noop') ||","      contains(github.event.comment.body, '.help') ||","      contains(github.event.comment.body, '.wcid') ||","      contains(github.event.comment.body, '.unlock')) }}","    runs-on: ubuntu-latest","    outputs: # set outputs for use in downstream jobs","      continue: ${{ steps.branch-deploy.outputs.continue }}","      noop: ${{ steps.branch-deploy.outputs.noop }}","      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}","      environment: ${{ steps.branch-deploy.outputs.environment }}","      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}","      sha: ${{ steps.branch-deploy.outputs.sha }}","      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}","      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}","      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}","","    steps:","      # execute the branch-deploy action","      - uses: github/branch-deploy@vX.X.X","        id: branch-deploy","        with:","          trigger: '.deploy'","          environment: 'github-pages'","          production_environments: 'github-pages'","          environment_targets: 'github-pages'","          skip_completing: true # we will complete the deployment manually in the 'result' job","          admins: 'false' # \u003c--- add your GitHub username here (if you want to use the admins feature)","","      - name: Capture deployment lock","        id: capture-lock","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","        run: |","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u003e/dev/null)\"; then","            printf 'sha=%s\\n' \"$lock_ref_sha\" \u003e\u003e \"$GITHUB_OUTPUT\"","          else","            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"","          fi","","  # build the github-pages site with Astro","  build:","    needs: trigger","    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true","    runs-on: ubuntu-latest","","    steps:","      - name: checkout","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ needs.trigger.outputs.sha }}","          persist-credentials: false","","      - name: build with astro","        uses: withastro/action@e3193ac80e18917ceaeb9f2d47019ad3b2c0416a # pin@v0.3.0","","  # deploy to GitHub Pages","  deploy:","    needs: [trigger, build]","    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true","    environment:","      name: github-pages","      url: ${{ steps.deployment.outputs.page_url }}","    runs-on: ubuntu-latest","","    steps:","      # deploy the site to GitHub Pages","      - name: deploy","        id: deployment","        uses: actions/deploy-pages@497da40f5225e762159b457c9ae5d6f75a136f5c # pin@v1.2.5","","  # update the deployment result - manually complete the deployment that was created by the branch-deploy action","  result:","    needs: [trigger, build, deploy]","    runs-on: ubuntu-latest","    # run even on failures but only if the trigger job set continue to true","    if: ${{ always() \u0026\u0026 needs.trigger.outputs.continue == 'true' }}","","    steps:","      # if a previous step failed, set a variable to use as the deployment status","      - name: set deployment status","        id: deploy-status","        if:","          ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||","          needs.deploy.result == 'failure' }}","        run: |","          echo \"DEPLOY_STATUS=failure\" \u003e\u003e $GITHUB_OUTPUT","","      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action","      - name: Create a deployment status","        env:","          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}","          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}","        run: |","          if [ -z \"${DEPLOY_STATUS}\" ]; then","            DEPLOY_STATUS=\"success\"","          fi","","          gh api \\","            --method POST \\","            \"repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses\" \\","            -f environment=\"${ENVIRONMENT}\" \\","            -f state=\"${DEPLOY_STATUS}\"","","      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action","      - name: Remove a non-sticky lock","        env:","          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}","          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          ISSUE_NUMBER: ${{ github.event.issue.number }}","          LOCK_ACTOR: ${{ github.actor }}","          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}","        run: |","          if [ -z \"${LOCK_REF_SHA}\" ]; then","            echo \"No captured deployment lock remains\"","            exit 0","          fi","","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"","          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"","","          if ! printf '%s' \"$lock_contents\" | jq -e \\","            --arg actor \"$LOCK_ACTOR\" \\","            --arg environment \"$ENVIRONMENT\" \\","            --arg link \"$lock_link\" \\","            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u003e/dev/null; then","            echo \"The captured deployment lock is sticky or belongs to another deployment\"","            exit 0","          fi","","          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"","          if gh api graphql \\","            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\","            -f repository=\"$repository_id\" \\","            -f name=\"refs/heads/${lock_branch}\" \\","            -f before=\"$LOCK_REF_SHA\" \u003e/dev/null; then","            echo \"Removed the original deployment lock\"","          else","            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"","          fi","","      # remove the default 'eyes' reaction from the comment that triggered the deployment","      # this reaction is added by the branch-deploy action by default","      - name: remove eyes reaction","        env:","          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}","        run: |","          if [ -n \"${INITIAL_REACTION_ID}\" ]; then","            gh api \\","              --method DELETE \\","              \"repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"","          fi","","      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment","      - name: rocket reaction","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}","        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7","        with:","          comment-id: ${{ needs.trigger.outputs.comment_id }}","          reactions: rocket","","      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment","      - name: failure reaction","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}","        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7","        with:","          comment-id: ${{ needs.trigger.outputs.comment_id }}","          reactions: '-1'","","      # if the deployment was successful, add a 'success' comment","      - name: success comment","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}","        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1","        with:","          issue-number: ${{ github.event.issue.number }}","          body: |","            ### Deployment Results ✅","","            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**","","            \u003e [View Live Deployment](${{ env.site_url }}) :link:","","      # if the deployment was not successful, add a 'failure' comment","      - name: failure comment","        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}","        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1","        with:","          issue-number: ${{ github.event.issue.number }}","          body: |","            ### Deployment Results ❌","","            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**","```","","## Multiple Jobs with GitHub Environments","","A detailed example using multiple jobs, [repository environments](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment), and Terraform. As mentioned in the [README](https://github.com/github/branch-deploy#about-environments-), a deployment completes when the workflow targeting that environment completes. In this example, the branch deployment action targets a separate environment than the \"actual\" deployment logic, which lets us control the completion of the branch deployment while being able to manage environments separately.","","```yaml","name: Branch Deploy","","on:","  issue_comment:","    types:","      - created","","env:","  # These variables are scoped to the **repository**.","  TF_VAR_image_repository: ${{ vars.IMAGE_REPOSITORY }}","","permissions:","  checks: read","  statuses: read","  contents: write","  deployments: write","  packages: read","  pull-requests: write","","jobs:","  start:","    name: Start Branch Deployment","    runs-on: ubuntu-latest","","    # Only start branch deployments on pull request comments.","    if: ${{ github.event.issue.pull_request }}","","    # The deployments environment is used by the branch-deploy workflow.","    environment: deployments","","    # Set the outputs to be used by the rest of the workflow.","    outputs:","      continue: ${{ steps.branch-deploy.outputs.continue }}","      noop: ${{ steps.branch-deploy.outputs.noop }}","      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}","      environment: ${{ steps.branch-deploy.outputs.environment }}","      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}","      sha: ${{ steps.branch-deploy.outputs.sha }}","      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}","      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}","      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}","","    steps:","      - name: Start Branch Deployment","        id: branch-deploy","        uses: github/branch-deploy@vX.X.X","        with:","          environment: development","          environment_targets: development,staging,production","          skip_completing: true","","      - name: Capture deployment lock","        id: capture-lock","        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}","        env:","          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}","          GH_REPO: ${{ github.repository }}","          GH_TOKEN: ${{ github.token }}","        run: |","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          if lock_ref_sha=\"$(gh api --method GET \"repos/{owner}/{repo}/git/ref/heads/${lock_branch}\" --jq '.object.sha' 2\u003e/dev/null)\"; then","            printf 'sha=%s\\n' \"$lock_ref_sha\" \u003e\u003e \"$GITHUB_OUTPUT\"","          else","            echo \"::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped\"","          fi","","  # This is the \"actual\" deployment logic. It uses the environment specified in","  # the branch deployment comment (e.g. `.deploy to development`).","  deploy:","    needs: start","","    name: Deploy","    runs-on: ubuntu-latest","","    # Only start after the branch deployment has initialized.","    if: ${{ needs.start.outputs.continue == 'true' }}","","    # Use the environment specified by the `.noop` or `.deploy` comment.","    environment: ${{ needs.start.outputs.environment }}","","    # Set the default working directory to `tf/` (or wherever your Terraform","    # code is located in your repository).","    defaults:","      run:","        working-directory: tf/","","    # Set the deployment outcome based on if `terraform plan` (.noop) or","    # `terraform apply` (.deploy) succeeded. Defaults to 'failure'.","    outputs:","      outcome: ${{ (steps.plan.outcome == 'success' || steps.apply.outcome == 'success') \u0026\u0026 'success' || 'failure' }}","","    # These variables/secrets are scoped to the **environment**.","    env:","      ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}","      ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}","      ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}","      TF_VAR_location: ${{ vars.AZURE_LOCATION }}","","    steps:","      - name: Checkout","        id: checkout","        uses: actions/checkout@v7.0.0","        with:","          ref: ${{ needs.start.outputs.sha }}","          persist-credentials: false","","      # Authenticate to Azure using OpenID Connect.","      - name: Authenticate to Azure (OIDC)","        id: azure-oidc","        uses: azure/login@v1","        with:","          client-id: ${{ env.ARM_CLIENT_ID }}","          subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}","          tenant-id: ${{ env.ARM_TENANT_ID }}","","      # Install Terraform on the runner.","      - name: Setup Terraform","        id: setup-terraform","        uses: hashicorp/setup-terraform@v2","        with:","          terraform_version: 1.5.5","","      # This example uses separate Terraform workspaces for each environment.","      - name: Terraform Init","        id: terraform-init","        env:","          ENVIRONMENT: ${{ needs.start.outputs.environment }}","        run: |","          terraform init -no-color","          terraform workspace select -or-create=true \"$ENVIRONMENT\"","","      # If this is a `.noop`, run `terraform plan` to see what would change.","      - name: Terraform Plan","        id: plan","        if: ${{ needs.start.outputs.noop == 'true' }}","        run: terraform plan -no-color","        continue-on-error: true","","      # If this is a `.deploy`, run `terraform apply` to apply the changes.","      - name: Terraform Apply","        id: apply","        if: ${{ needs.start.outputs.noop != 'true' }}","        run: terraform apply -no-color -auto-approve","        continue-on-error: true","","      # Get the output from the plan/apply step.","      - name: Save Terraform Output","        id: output","        env:","          PLAN_STDOUT: ${{ steps.plan.outputs.stdout }}","          APPLY_STDOUT: ${{ steps.apply.outputs.stdout }}","        run: |","          if [ -z \"$PLAN_STDOUT\" ]","          then","            echo \"$APPLY_STDOUT\" \u003e tf_output.txt","          else","            echo \"$PLAN_STDOUT\" \u003e tf_output.txt","          fi","","      # Upload the plan/apply output as an artifact so that it can be used in","      # the `stop` job.","      - name: Upload Terraform Output","        id: upload","        uses: actions/upload-artifact@v3","        with:","          name: tf_output","          path: tf/tf_output.txt","","  stop:","    needs:","      - start","      - deploy","","    name: Stop Branch Deployment","    runs-on: ubuntu-latest","","    # Always run this job if the branch deployment was started.","    if: ${{ always() \u0026\u0026 needs.start.outputs.continue == 'true' }}","","    # Switch back to the deployments environment to update the branch","    # deployment status.","    environment: deployments","","    # Get the outputs from the `start` job. These are needed to finish the","    # branch deployment, comment on the PR, update reactions, etc.","    env:","      ACTOR: ${{ needs.start.outputs.actor_handle }}","      COMMENT_ID: ${{ needs.start.outputs.comment_id }}","      DEPLOYMENT_ID: ${{ needs.start.outputs.deployment_id }}","      DEPLOYMENT_STATUS: ${{ needs.deploy.outputs.outcome || 'failure' }}","      ENVIRONMENT: ${{ needs.start.outputs.environment }}","      GH_REPO: ${{ github.repository }}","      GH_TOKEN: ${{ github.token }}","      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}","      INITIAL_REACTION_ID: ${{ needs.start.outputs.initial_reaction_id }}","      ISSUE_NUMBER: ${{ github.event.issue.number }}","      LOCK_ACTOR: ${{ github.actor }}","      LOCK_REF_SHA: ${{ needs.start.outputs.lock_ref_sha }}","      NOOP: ${{ needs.start.outputs.noop }}","      SHA: ${{ needs.start.outputs.sha }}","      REPOSITORY: ${{ github.repository }}","","    steps:","      # Tf this was not a `.noop` deployment, set the status.","      - if: ${{ env.NOOP != 'true' }}","        name: Set Deployment Status","        id: set-status","        run: |","          gh api --method POST \\","            \"repos/${REPOSITORY}/deployments/${DEPLOYMENT_ID}/statuses\" \\","            -f environment=\"${ENVIRONMENT}\" \\","            -f state=\"${DEPLOYMENT_STATUS}\"","","      # Remove the non-sticky lock for either a `.noop` or `.deploy`.","      - name: Remove Non-Sticky Lock","        id: remove-lock","        run: |","          if [ -z \"${LOCK_REF_SHA}\" ]; then","            echo \"No captured deployment lock remains\"","            exit 0","          fi","","          lock_branch=\"$(printf '%s' \"$ENVIRONMENT\" | jq -Rsr 'gsub(\"\\\\s\"; \"-\")')-branch-deploy-lock\"","          lock_contents=\"$(gh api --method GET \"repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}\" --jq '.content' | base64 --decode)\"","          lock_link=\"${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}\"","","          if ! printf '%s' \"$lock_contents\" | jq -e \\","            --arg actor \"$LOCK_ACTOR\" \\","            --arg environment \"$ENVIRONMENT\" \\","            --arg link \"$lock_link\" \\","            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' \u003e/dev/null; then","            echo \"The captured deployment lock is sticky or belongs to another deployment\"","            exit 0","          fi","","          repository_id=\"$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')\"","          if gh api graphql \\","            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: \"0000000000000000000000000000000000000000\"}]}) { clientMutationId } }' \\","            -f repository=\"$repository_id\" \\","            -f name=\"refs/heads/${lock_branch}\" \\","            -f before=\"$LOCK_REF_SHA\" \u003e/dev/null; then","            echo \"Removed the original deployment lock\"","          else","            echo \"::warning::The original deployment lock changed; leaving the current lock in place\"","          fi","","      # Remove the trigger reaction added to the user's comment.","      - name: Remove Trigger Reaction","        id: remove-reaction","        run: |","          if [ -n \"${INITIAL_REACTION_ID}\" ]; then","            gh api --method DELETE \\","              \"repos/${REPOSITORY}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}\"","          fi","","      # Add a new reaction based on if the deployment succeeded or failed.","      - name: Add Reaction","        id: add-reaction","        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7","        env:","          REACTION: ${{ env.DEPLOYMENT_STATUS == 'success' \u0026\u0026 'rocket' || '-1' }}","        with:","          comment-id: ${{ env.COMMENT_ID }}","          reactions: ${{ env.DEPLOYMENT_STATUS == 'success' \u0026\u0026 'rocket' || '-1' }}","","      # If the plan/apply didn't run because of a failure, this step will also","      # fail, hence setting continue-on-error.","      - name: Get Terraform Output Artifact","        id: get-artifact","        uses: actions/download-artifact@v3","        with:","          name: tf_output","        continue-on-error: true","","      # Add a success comment, including the plan/apply output (if present).","      - if: ${{ env.DEPLOYMENT_STATUS == 'success' }}","        name: Add Success Comment","        id: success-comment","        uses: actions/github-script@v6","        with:","          script: |","            const fs = require('fs')","","            let output","            try { output = fs.readFileSync('tf_output.txt', 'utf8') }","            catch (err) { output = 'No Terraform output!' }","","            await github.rest.issues.createComment({","              issue_number: context.issue.number,","              owner: context.repo.owner,","              repo: context.repo.repo,","              body: `### Deployment Results :white_check_mark:","","            **${process.env.ACTOR}** successfully ${ process.env.NOOP === 'true' ? '**noop** deployed' : 'deployed' } sha \\`${process.env.SHA}\\` to **${process.env.ENVIRONMENT}**","","            \u003cdetails\u003e\u003csummary\u003eShow Results\u003c/summary\u003e","","            \\`\\`\\`terraform\\n${ output }\\n\\`\\`\\`","","            \u003c/details\u003e`","            })","","      # Add a failure comment, including the plan/apply output (if present).","      - if: ${{ env.DEPLOYMENT_STATUS == 'failure' }}","        name: Add Failure Comment","        id: failure-comment","        uses: actions/github-script@v6","        with:","          script: |","            const fs = require('fs')","","            let output","            try { output = fs.readFileSync('tf_output.txt', 'utf8') }","            catch (err) { output = 'No Terraform output!' }","","            await github.rest.issues.createComment({","              issue_number: context.issue.number,","              owner: context.repo.owner,","              repo: context.repo.repo,","              body: `### Deployment Results :x:","","            **${process.env.ACTOR}** had a failure when ${ process.env.NOOP === 'true' ? '**noop** deploying' : 'deploying' } sha \\`${process.env.SHA}\\` to **${process.env.ENVIRONMENT}**","","            \u003cdetails\u003e\u003csummary\u003eShow Results\u003c/summary\u003e","","            \\`\\`\\`terraform\\n${ output }\\n\\`\\`\\`","","            \u003c/details\u003e`","            })","","      # If the deployment failed, fail the workflow.","      - if: ${{ env.DEPLOYMENT_STATUS == 'failure' }}","        name: Fail Workflow","        id: fail-workflow","        run: |","          echo \"There was a deployment problem...failing the workflow!\"","          exit 1","```","","---","","Are you using the `branch-deploy` Action and want your example included here? Open a pull request and we'll add it!"],"stylingDirectives":[[[0,10,"pl-mh"],[2,10,"pl-en"]],[],[],[],[[0,189,"pl-ent"],[0,2,"pl-ent"],[42,43,"pl-s"],[43,76,"pl-c1"],[76,77,"pl-s"],[87,88,"pl-s"],[88,93,"pl-c1"],[93,94,"pl-s"],[104,105,"pl-s"],[119,120,"pl-s"],[120,121,"pl-s"],[121,173,"pl-corl"],[173,174,"pl-s"]],[[0,0,"pl-ent"]],[[0,20,"pl-mh"],[3,20,"pl-en"]],[],[],[],[[0,1,"pl-v"],[2,3,"pl-s"],[11,12,"pl-s"],[12,13,"pl-s"],[13,22,"pl-corl"],[22,23,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[22,23,"pl-s"],[23,24,"pl-s"],[24,42,"pl-corl"],[42,43,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[19,20,"pl-s"],[20,21,"pl-s"],[21,36,"pl-corl"],[36,37,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[14,15,"pl-s"],[15,16,"pl-s"],[16,26,"pl-corl"],[26,27,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[37,38,"pl-s"],[38,39,"pl-s"],[39,72,"pl-corl"],[72,73,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[11,12,"pl-s"],[12,13,"pl-s"],[13,20,"pl-corl"],[20,21,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[12,13,"pl-s"],[13,14,"pl-s"],[14,22,"pl-corl"],[22,23,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[8,9,"pl-s"],[9,10,"pl-s"],[10,14,"pl-corl"],[14,15,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[21,22,"pl-s"],[22,23,"pl-s"],[23,40,"pl-corl"],[40,41,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[23,24,"pl-s"],[24,25,"pl-s"],[25,44,"pl-corl"],[44,45,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[18,19,"pl-s"],[19,20,"pl-s"],[20,34,"pl-corl"],[34,35,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[45,46,"pl-s"],[46,47,"pl-s"],[47,88,"pl-corl"],[88,89,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[46,47,"pl-s"],[47,48,"pl-s"],[48,90,"pl-corl"],[90,91,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[43,44,"pl-s"],[44,45,"pl-s"],[45,84,"pl-corl"],[84,85,"pl-s"]],[],[[0,17,"pl-mh"],[3,17,"pl-en"]],[],[],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,8,"pl-c1"],[8,9,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,4,"pl-ent"],[6,19,"pl-s"]],[],[[0,2,"pl-ent"]],[[2,15,"pl-ent"]],[[4,9,"pl-ent"],[11,20,"pl-s"]],[],[[0,75,"pl-c"],[0,1,"pl-c"]],[[0,11,"pl-ent"]],[[2,15,"pl-ent"],[17,22,"pl-s"]],[[2,13,"pl-ent"],[15,20,"pl-s"]],[[2,10,"pl-ent"],[12,17,"pl-s"]],[[2,8,"pl-ent"],[10,14,"pl-s"]],[[2,10,"pl-ent"],[12,16,"pl-s"]],[],[[0,4,"pl-ent"]],[[2,8,"pl-ent"]],[[4,8,"pl-ent"],[10,16,"pl-s"]],[[4,11,"pl-ent"],[13,26,"pl-s"]],[[4,6,"pl-ent"],[8,47,"pl-s"],[47,82,"pl-c"],[47,48,"pl-c"]],[],[[4,9,"pl-ent"]],[[6,32,"pl-c"],[6,7,"pl-c"]],[[8,12,"pl-ent"],[14,27,"pl-s"]],[[8,10,"pl-ent"],[12,25,"pl-s"]],[[8,12,"pl-ent"],[14,41,"pl-s"]],[],[[8,72,"pl-c"],[8,9,"pl-c"]],[[8,12,"pl-ent"],[14,37,"pl-s"]],[[8,12,"pl-ent"]],[[10,13,"pl-ent"],[15,53,"pl-s"]],[[10,29,"pl-ent"],[31,36,"pl-c1"]],[],[[8,91,"pl-c"],[8,9,"pl-c"]],[[8,12,"pl-ent"],[14,25,"pl-s"]],[[8,10,"pl-ent"],[12,111,"pl-s"]],[[8,11,"pl-ent"],[13,39,"pl-s"],[39,72,"pl-c"],[39,40,"pl-c"]],[],[[8,93,"pl-c"],[8,9,"pl-c"]],[[8,12,"pl-ent"],[14,20,"pl-s"]],[[8,10,"pl-ent"],[12,111,"pl-s"]],[[8,11,"pl-ent"],[13,34,"pl-s"],[34,67,"pl-c"],[34,35,"pl-c"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,0,"pl-s"]],[[0,12,"pl-s"]],[[0,0,"pl-s"]],[[0,92,"pl-s"]],[[0,0,"pl-s"]],[[0,3,"pl-s"],[2,3,"pl-pds"],[3,35,"pl-s"]],[[2,11,"pl-s"],[2,3,"pl-pds"],[10,11,"pl-pds"],[12,38,"pl-s"]],[],[[0,95,"pl-s"]],[],[[0,161,"pl-s"]],[],[[0,7,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,19,"pl-s"]],[[0,0,"pl-s"]],[[0,3,"pl-s"]],[[0,16,"pl-s"]],[[0,20,"pl-s"]],[[0,0,"pl-s"]],[[0,61,"pl-s"]],[[0,4,"pl-s"]],[[0,25,"pl-s"]],[[0,0,"pl-s"]],[[0,75,"pl-s"]],[[0,12,"pl-s"]],[[0,22,"pl-s"]],[[0,20,"pl-s"]],[[0,17,"pl-s"]],[[0,14,"pl-s"]],[[0,16,"pl-s"]],[[0,0,"pl-s"]],[[0,5,"pl-s"]],[[0,9,"pl-s"]],[[0,16,"pl-s"]],[[0,26,"pl-s"]],[[0,82,"pl-s"]],[[0,86,"pl-s"]],[[0,13,"pl-s"]],[[0,10,"pl-s"]],[[0,106,"pl-s"]],[[0,0,"pl-s"]],[[0,10,"pl-s"]],[[0,32,"pl-s"]],[[0,27,"pl-s"]],[[0,25,"pl-s"]],[[0,41,"pl-s"]],[[0,0,"pl-s"]],[[0,72,"pl-s"]],[[0,22,"pl-s"]],[[0,58,"pl-s"]],[[0,37,"pl-s"]],[[0,13,"pl-s"]],[[0,53,"pl-s"]],[[0,36,"pl-s"]],[[0,0,"pl-s"]],[[0,47,"pl-s"]],[[0,89,"pl-s"]],[[0,58,"pl-s"]],[[0,13,"pl-s"]],[[0,88,"pl-s"]],[[0,67,"pl-s"]],[[0,0,"pl-s"]],[[0,53,"pl-s"]],[[0,28,"pl-s"]],[[0,58,"pl-s"]],[[0,27,"pl-s"]],[[0,0,"pl-s"]],[[0,51,"pl-s"]],[[0,28,"pl-s"]],[[0,111,"pl-s"]],[[0,16,"pl-s"]],[[0,37,"pl-s"]],[[0,85,"pl-s"]],[[0,0,"pl-s"]],[[0,54,"pl-s"]],[[0,29,"pl-s"]],[[0,111,"pl-s"]],[[0,17,"pl-s"]],[[0,52,"pl-s"]],[[0,85,"pl-s"]],[[0,0,"pl-s"]],[[0,154,"pl-s"]],[[0,35,"pl-s"]],[[0,111,"pl-s"]],[[0,12,"pl-s"]],[[0,53,"pl-s"]],[[0,14,"pl-s"]],[[0,82,"pl-s"],[77,79,"pl-cce"]],[[0,71,"pl-s"],[26,28,"pl-cce"]],[[0,84,"pl-s"],[79,81,"pl-cce"]],[[0,14,"pl-s"]],[[0,11,"pl-s"]],[[0,54,"pl-s"],[37,54,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,111,"pl-s"],[0,111,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,71,"pl-s"],[0,71,"pl-s1"]],[[0,84,"pl-s"],[0,84,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,11,"pl-s"],[0,11,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,113,"pl-s"],[0,113,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,146,"pl-s"],[0,146,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,147,"pl-s"],[0,147,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,79,"pl-s"],[0,79,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,91,"pl-s"],[0,91,"pl-s1"]],[[0,68,"pl-s"],[0,68,"pl-s1"]],[[0,95,"pl-s"],[0,95,"pl-s1"]],[[0,85,"pl-s"],[0,85,"pl-s1"]],[[0,156,"pl-s"],[0,156,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,4,"pl-s"],[0,4,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,23,"pl-s"],[0,23,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,200,"pl-s"],[0,200,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,60,"pl-s"],[0,60,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,60,"pl-s"],[0,60,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,70,"pl-s"],[0,70,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,48,"pl-s"],[0,48,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,68,"pl-s"],[0,68,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,66,"pl-s"],[0,66,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,62,"pl-s"],[0,62,"pl-s1"]],[[0,99,"pl-s"],[0,99,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,80,"pl-s"],[0,80,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,111,"pl-s"],[0,111,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,83,"pl-s"],[0,83,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,111,"pl-s"],[0,111,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,98,"pl-s"],[0,98,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,89,"pl-s"],[0,89,"pl-s1"]],[[0,92,"pl-s"],[0,92,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,66,"pl-s"],[0,66,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,62,"pl-s"],[0,62,"pl-s1"]],[[0,84,"pl-s"],[0,84,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,11,"pl-s"],[0,11,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,146,"pl-s"],[0,146,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,147,"pl-s"],[0,147,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,62,"pl-s"],[0,62,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,8,"pl-s"],[0,8,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,83,"pl-s"],[0,83,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,70,"pl-s"],[0,70,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,21,"pl-s"],[0,21,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,15,"pl-s"],[0,15,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,48,"pl-s"],[0,48,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,84,"pl-s"],[0,84,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,343,"pl-s"],[0,343,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,4,"pl-s"],[0,4,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,62,"pl-s"],[0,62,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,156,"pl-s"],[0,156,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,94,"pl-s"],[0,94,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,84,"pl-s"],[0,84,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,212,"pl-s"],[0,212,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,58,"pl-s"],[0,58,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,23,"pl-s"],[0,23,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,6,"pl-s"],[0,6,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,118,"pl-s"],[0,118,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,48,"pl-s"],[0,48,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,156,"pl-s"],[0,156,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,111,"pl-s"],[0,111,"pl-s1"]],[[0,87,"pl-s"],[0,87,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,80,"pl-s"],[0,80,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,103,"pl-s"],[0,103,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,77,"pl-s"],[0,77,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,161,"pl-s"],[0,161,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,21,"pl-s"],[0,21,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,92,"pl-s"],[0,92,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,171,"pl-s"],[0,171,"pl-s1"]],[[0,93,"pl-s"],[0,93,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,102,"pl-s"],[0,102,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,23,"pl-s"],[0,23,"pl-s1"]],[[0,170,"pl-s"],[0,170,"pl-s1"]],[[0,93,"pl-s"],[0,93,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,99,"pl-s"],[0,99,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,21,"pl-s"],[0,21,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,107,"pl-s"],[0,107,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,124,"pl-s"],[0,124,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,161,"pl-s"],[0,161,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,74,"pl-s"],[0,74,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,92,"pl-s"],[0,92,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,93,"pl-s"],[0,93,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,62,"pl-s"],[0,62,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,68,"pl-s"],[0,68,"pl-s1"]],[[0,93,"pl-s"],[0,93,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,352,"pl-s"],[0,352,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,74,"pl-s"],[0,74,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,139,"pl-s"],[0,139,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,113,"pl-s"],[0,113,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,95,"pl-s"],[0,95,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,100,"pl-s"],[0,100,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,112,"pl-s"],[0,112,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,88,"pl-s"],[0,88,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,105,"pl-s"],[0,105,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,74,"pl-s"],[0,74,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,144,"pl-s"],[0,144,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,46,"pl-s"],[0,46,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,146,"pl-s"],[0,146,"pl-s1"]],[[0,90,"pl-s"],[0,90,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,87,"pl-s"],[0,87,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,269,"pl-s"],[0,269,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,89,"pl-s"],[0,89,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,79,"pl-s"],[0,79,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,50,"pl-s"],[0,50,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,99,"pl-s"],[0,99,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,110,"pl-s"],[0,110,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,112,"pl-s"],[0,112,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,104,"pl-s"],[0,104,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,162,"pl-s"],[0,162,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,104,"pl-s"],[0,104,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,169,"pl-s"],[0,169,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,254,"pl-s"],[0,254,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,157,"pl-s"],[0,157,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,4,"pl-s"],[0,4,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,122,"pl-s"],[0,122,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,94,"pl-s"],[0,94,"pl-s1"]],[[0,102,"pl-s"],[0,102,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,139,"pl-s"],[0,139,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,113,"pl-s"],[0,113,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,8,"pl-s"],[0,8,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,106,"pl-s"],[0,106,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,100,"pl-s"],[0,100,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,70,"pl-s"],[0,70,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,152,"pl-s"],[0,152,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,91,"pl-s"],[0,91,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,78,"pl-s"],[0,78,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,97,"pl-s"],[0,97,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,106,"pl-s"],[0,106,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,88,"pl-s"],[0,88,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,112,"pl-s"],[0,112,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,11,"pl-s"],[0,11,"pl-s1"]],[[0,85,"pl-s"],[0,85,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,105,"pl-s"],[0,105,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,74,"pl-s"],[0,74,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,144,"pl-s"],[0,144,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,46,"pl-s"],[0,46,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,146,"pl-s"],[0,146,"pl-s1"]],[[0,90,"pl-s"],[0,90,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,87,"pl-s"],[0,87,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,269,"pl-s"],[0,269,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,89,"pl-s"],[0,89,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,79,"pl-s"],[0,79,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,50,"pl-s"],[0,50,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,99,"pl-s"],[0,99,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,110,"pl-s"],[0,110,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,112,"pl-s"],[0,112,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,104,"pl-s"],[0,104,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,162,"pl-s"],[0,162,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,104,"pl-s"],[0,104,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,169,"pl-s"],[0,169,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,232,"pl-s"],[0,232,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,169,"pl-s"],[0,169,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,71,"pl-s"],[0,71,"pl-s1"]],[[0,4,"pl-s"],[0,4,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,122,"pl-s"],[0,122,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,94,"pl-s"],[0,94,"pl-s1"]],[[0,102,"pl-s"],[0,102,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,139,"pl-s"],[0,139,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,113,"pl-s"],[0,113,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,8,"pl-s"],[0,8,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,106,"pl-s"],[0,106,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,84,"pl-s"],[0,84,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,106,"pl-s"],[0,106,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,88,"pl-s"],[0,88,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,112,"pl-s"],[0,112,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,11,"pl-s"],[0,11,"pl-s1"]],[[0,85,"pl-s"],[0,85,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,105,"pl-s"],[0,105,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,74,"pl-s"],[0,74,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,144,"pl-s"],[0,144,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,46,"pl-s"],[0,46,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,146,"pl-s"],[0,146,"pl-s1"]],[[0,90,"pl-s"],[0,90,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,87,"pl-s"],[0,87,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,269,"pl-s"],[0,269,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,89,"pl-s"],[0,89,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,79,"pl-s"],[0,79,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,50,"pl-s"],[0,50,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,99,"pl-s"],[0,99,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,110,"pl-s"],[0,110,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,112,"pl-s"],[0,112,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,104,"pl-s"],[0,104,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,162,"pl-s"],[0,162,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,104,"pl-s"],[0,104,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,56,"pl-s"],[0,56,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,169,"pl-s"],[0,169,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,592,"pl-s"],[0,592,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,15,"pl-s"],[0,15,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,4,"pl-s"],[0,4,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,5,"pl-s"],[0,5,"pl-s1"]],[[0,8,"pl-s"],[0,8,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,46,"pl-s"],[0,46,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,139,"pl-s"],[0,139,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,113,"pl-s"],[0,113,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,79,"pl-s"],[0,79,"pl-s1"]],[[0,66,"pl-s"],[0,66,"pl-s1"]],[[0,9,"pl-s"],[0,9,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,30,"pl-s"],[0,30,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,72,"pl-s"],[0,72,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,117,"pl-s"],[0,117,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,8,"pl-s"],[0,8,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,20,"pl-s"],[0,20,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,51,"pl-s"],[0,51,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,77,"pl-s"],[0,77,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,67,"pl-s"],[0,67,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,75,"pl-s"],[0,75,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,17,"pl-s"],[0,17,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,48,"pl-s"],[0,48,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,34,"pl-s"],[0,34,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,48,"pl-s"],[0,48,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,77,"pl-s"],[0,77,"pl-s1"]],[[0,23,"pl-s"],[0,23,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,7,"pl-s"],[0,7,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,63,"pl-s"],[0,63,"pl-s1"]],[[0,65,"pl-s"],[0,65,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,28,"pl-s"],[0,28,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,74,"pl-s"],[0,74,"pl-s1"]],[[0,66,"pl-s"],[0,66,"pl-s1"]],[[0,8,"pl-s"],[0,8,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,57,"pl-s"],[0,57,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,41,"pl-s"],[0,41,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,10,"pl-s"],[0,10,"pl-s1"]],[[0,61,"pl-s"],[0,61,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,35,"pl-s"],[0,35,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,32,"pl-s"],[0,32,"pl-s1"]],[[0,73,"pl-s"],[0,73,"pl-s1"]],[[0,45,"pl-s"],[0,45,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,23,"pl-s"],[0,23,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,144,"pl-s"],[0,144,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,39,"pl-s"],[0,39,"pl-s1"]],[[0,46,"pl-s"],[0,46,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,146,"pl-s"],[0,146,"pl-s1"]],[[0,90,"pl-s"],[0,90,"pl-s1"]],[[0,18,"pl-s"],[0,18,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,87,"pl-s"],[0,87,"pl-s1"]],[[0,29,"pl-s"],[0,29,"pl-s1"]],[[0,269,"pl-s"],[0,269,"pl-s1"]],[[0,44,"pl-s"],[0,44,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,54,"pl-s"],[0,54,"pl-s1"]],[[0,55,"pl-s"],[0,55,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,101,"pl-s"],[0,101,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,64,"pl-s"],[0,64,"pl-s1"]],[[0,37,"pl-s"],[0,37,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,50,"pl-s"],[0,50,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,98,"pl-s"],[0,98,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,74,"pl-s"],[0,74,"pl-s1"]],[[0,26,"pl-s"],[0,26,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,86,"pl-s"],[0,86,"pl-s1"]],[[0,12,"pl-s"],[0,12,"pl-s1"]],[[0,81,"pl-s"],[0,81,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,82,"pl-s"],[0,82,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,78,"pl-s"],[0,78,"pl-s1"]],[[0,46,"pl-s"],[0,46,"pl-s1"]],[[0,43,"pl-s"],[0,43,"pl-s1"]],[[0,24,"pl-s"],[0,24,"pl-s1"]],[[0,42,"pl-s"],[0,42,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,31,"pl-s"],[0,31,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,62,"pl-s"],[0,62,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,178,"pl-s"],[0,178,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,48,"pl-s"],[0,48,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,23,"pl-s"],[0,23,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,76,"pl-s"],[0,76,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,33,"pl-s"],[0,33,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,13,"pl-s"],[0,13,"pl-s1"]],[[0,19,"pl-s"],[0,19,"pl-s1"]],[[0,36,"pl-s"],[0,36,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,22,"pl-s"],[0,22,"pl-s1"]],[[0,69,"pl-s"],[0,69,"pl-s1"]],[[0,59,"pl-s"],[0,59,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,49,"pl-s"],[0,49,"pl-s1"]],[[0,40,"pl-s"],[0,40,"pl-s1"]],[[0,38,"pl-s"],[0,38,"pl-s1"]],[[0,47,"pl-s"],[0,47,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,186,"pl-s"],[0,186,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,48,"pl-s"],[0,48,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,23,"pl-s"],[0,23,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,52,"pl-s"],[0,52,"pl-s1"]],[[0,53,"pl-s"],[0,53,"pl-s1"]],[[0,27,"pl-s"],[0,27,"pl-s1"]],[[0,25,"pl-s"],[0,25,"pl-s1"]],[[0,14,"pl-s"],[0,14,"pl-s1"]],[[0,71,"pl-s"],[0,71,"pl-s1"]],[[0,16,"pl-s"],[0,16,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,3,"pl-s"],[0,3,"pl-s1"]],[[0,0,"pl-s"],[0,0,"pl-s1"]],[[0,115,"pl-s"],[0,115,"pl-s1"]]],"colorizedLines":null}},"title":"branch-deploy/docs/examples.md at main · github/branch-deploy","appPayload":{},"meta":{"title":"branch-deploy/docs/examples.md at main · github/branch-deploy"}}</script>
  <div data-target="react-app.reactRoot"><meta name="github-code-view-meta-stats" id="github-code-view-meta-stats" data-hydrostats="publish"/> <!-- --> <a hidden="" id="code-view-repo-link" href="/github/branch-deploy" data-discover="true"></a> <div class="d-none"></div><div><div style="--spacing:var(--spacing-none)" class="prc-PageLayout-PageLayoutRoot--KH-d" data-component="SplitPageLayout" data-has-sidebar="true"><div class="prc-PageLayout-SidebarWrapper-kLG4B CopilotSidePanelSidebar-module__SidePanel__L3O0C CopilotSidePanelSidebar-module__HiddenSidePanel__TBRGn" style="--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="end" data-sticky="true" data-responsive-variant="fullscreen"><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-SidebarVerticalDivider-0Rl0V" data-component="PageLayout.VerticalDivider" data-variant="line" data-position="end" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="450" aria-valuemax="768" aria-valuenow="544" aria-valuetext="Pane width 544 pixels" tabindex="0"></div></div><div class="prc-PageLayout-Sidebar-iciWg" data-component="SplitPageLayout.Sidebar" data-resizable="true" style="--spacing:var(--spacing-normal);--pane-min-width:450px;--pane-max-width:768px;--pane-width-custom:544px;--pane-width-size:var(--pane-width-custom);--pane-width:544px"><div class="height-full" data-testid="copilot-code-view-side-panel"><div id="copilot-side-panel-content" class="height-full"></div></div></div></div><div class="prc-PageLayout-PageLayoutWrapper-2BhU2" data-width="full"><div class="prc-PageLayout-PageLayoutContent-BneH9"><div id="repos-file-tree-sidebar" class="CodeViewFileTreeLayout-module__sidebar__n_Aau" tabindex="0"><div class="prc-PageLayout-PaneWrapper-pHPop ReposFileTreePane-module__Pane__rBZpI ReposFileTreePane-module__HideTree__AYZnm ReposFileTreePane-module__HidePane__VHAVt" style="--offset-header:0px;--spacing-row:var(--spacing-none);--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="start" data-sticky="true"><div class="prc-PageLayout-HorizontalDivider-JLVqp prc-PageLayout-PaneHorizontalDivider-9tbnE" data-component="PageLayout.HorizontalDivider" data-variant-regular="none" data-variant-narrow="none" data-position="start" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)"></div><div class="prc-PageLayout-Pane-AyzHK" data-component="SplitPageLayout.Pane" data-resizable="true" style="--spacing:var(--spacing-none);--pane-min-width:256px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));--pane-width-size:var(--pane-width-large);--pane-width:320px"></div><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-PaneVerticalDivider-le57g" data-component="PageLayout.VerticalDivider" data-variant-narrow="none" data-variant-regular="line" data-variant-wide="line" data-position="start" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="256" aria-valuemax="600" aria-valuenow="320" aria-valuetext="Pane width 320 pixels" tabindex="0"></div></div></div></div><div data-component="SplitPageLayout.Content" class="prc-PageLayout-ContentWrapper-gR9eG"><div class="prc-PageLayout-Content-xWL-A" data-width="full" style="--spacing:var(--spacing-none)"><div class="SharedPageLayout-module__content__IwGAp" data-selector="repos-split-pane-content" id="repos-split-pane-content" tabindex="0"> <!-- --> <div class="container CodeViewHeader-module__Box__JkPOb"><div class="CodeViewHeader-module__StickyHeader__Qn7UN" id="StickyHeader"><div class="CodeViewHeader-module__Box_1__SbNDV"><div class="CodeViewHeader-module__Box_2__TB46f"><div class="react-code-view-header-wrap--narrow CodeViewHeader-module__Box_3__q1zUL"><div class="CodeViewHeader-module__treeToggleWrapper__RQ__9"><h2 class="use-tree-pane-module__Heading__s4QbZ prc-Heading-Heading-MtWFE" data-component="Heading"><button data-component="Button" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="prc-Button-ButtonBase-9n-Xk ExpandFileTreeButton-module__Button_1__Svs95" data-loading="false" data-size="medium" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Files</span></span></button><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-9n-Xk position-relative ExpandFileTreeButton-module__expandButton__hDOcv ExpandFileTreeButton-module__filesButtonBreakpoint__zEvz3 fgColor-muted prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_4lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="se" data-component="Tooltip" aria-hidden="true" id="_R_4lla9lik5_">Expand file tree</span><div class="d-none"></div></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="react-code-view-header-mb--narrow CodeViewHeader-module__Box_5__MQ0hL"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__lg__Rjz0A"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/github/branch-deploy/tree/main" data-discover="true">branch-deploy</a></li><li class="Breadcrumb-module__listItem__Ib0x_"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><a class="Breadcrumb-module__directoryLink__kQy_t prc-Link-Link-9ZwDx" data-component="Link" href="/github/branch-deploy/tree/main/docs" data-discover="true">docs</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__lg__Rjz0A prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="file-name-id">examples.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lla9lik5_">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><div><div class="CodeViewHeader-module__FileResultsList__JDzUy"><span class="d-flex FileResultsList-module__FilesSearchBox__ivVkc TextInput-wrapper prc-components-TextInputWrapper-Hpdqi prc-components-TextInputBaseWrapper-wY-n0" data-no-trailing-action="true" data-component="TextInput" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id="_R_1cpla9lik5_" aria-hidden="true" data-component="TextInput.LeadingVisual"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellCheck="false" placeholder="Go to file" aria-describedby="_R_1cpla9lik5_ _R_1cpla9lik5H1_" data-component="input" class="prc-components-Input-IwWrt" value=""/><span class="TextInput-icon" id="_R_1cpla9lik5H1_" aria-hidden="true" data-component="TextInput.TrailingVisual"></span></span></div><div class="d-none"></div></div><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7p9la9lik5_" id="_R_99la9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7p9la9lik5_">More file actions</span></div></div></div><div class="react-code-view-header-element--narrow"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7pdla9lik5_" id="_R_9dla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7pdla9lik5_">More file actions</span></div></div></div></div></div></div></div><div class="CodeView-module__contentWrapper__cG2JH"><div class="react-code-view-bottom-padding"><div class="BlobTopBanners-module__Box__v_nvx"></div></div> <div class="d-none"></div><div class="d-flex flex-column border rounded-2 tmp-mb-3 pl-1"><div class="LatestCommit-module__Box__B25ZT"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">History</h2><a data-component="LinkButton" href="/github/branch-deploy/commits/main/docs/examples.md" class="prc-Button-ButtonBase-9n-Xk d-none d-lg-flex LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><a data-component="LinkButton" aria-label="View commit history for this file." href="/github/branch-deploy/commits/main/docs/examples.md" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby="_R_4mlala9lik5_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" role="tooltip" aria-hidden="true" id="_R_4mlala9lik5_">History</span></div></div></div></div></div><div class="d-flex flex-row"><div class="container BlobViewContent-module__blobContainer__DtH2d"><div class="react-code-size-details-banner BlobViewContent-module__codeSizeDetails__e5sUw"><div class="react-code-size-details-banner CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="73.3 KB" style="--truncate-max-width:100%"><span>1907 lines (1600 loc) · 73.3 KB</span></div></div></div></div><div class="react-blob-view-header-sticky BlobViewContent-module__stickyHeader__VwxB5" id="repos-sticky-header"><div class="BlobViewHeader-module__Box__yhm9u"><div class="react-blob-sticky-header"><div class="FileNameStickyHeader-module__outerWrapper__ZL4Xc FileNameStickyHeader-module__outerWrapperHidden__Zpynk"><div class="FileNameStickyHeader-module__Box_1__Hazu5"><div class="FileNameStickyHeader-module__Box_2__hoolP"><div class="FileNameStickyHeader-module__Box_3__MVKsk"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="FileNameStickyHeader-module__Box_4__FLhtt"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__md__Wb1Gs"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/github/branch-deploy/tree/main" data-discover="true">branch-deploy</a></li><li class="Breadcrumb-module__listItem__Ib0x_"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><a class="Breadcrumb-module__directoryLink__kQy_t prc-Link-Link-9ZwDx" data-component="Link" href="/github/branch-deploy/tree/main/docs" data-discover="true">docs</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__md__Wb1Gs prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="sticky-file-name-id">examples.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lcpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lcpala9lik5_">Copy path</span></div></div></div><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk FileNameStickyHeader-module__Button__LSEU_ FileNameStickyHeader-module__GoToTopButton__nxAFn" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Top</span></span></button></div></div></div><div class="BlobViewHeader-module__Box_1__VEmuQ"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">File metadata and controls</h2><div class="BlobViewHeader-module__Box_2__icUs2"><ul aria-label="File view" class="prc-SegmentedControl-SegmentedControl-lqIXp BlobTabButtons-module__SegmentedControl__jen2u" data-variant="default" data-size="small" data-component="SegmentedControl"><li class="prc-SegmentedControl-Item-tSCQh" data-selected="" data-component="SegmentedControl.Button"><button aria-pressed="true" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:transparent"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><div class="d-none"></div><div class="react-code-size-details-in-header CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="73.3 KB" style="--truncate-max-width:100%"><span>1907 lines (1600 loc) · 73.3 KB</span></div></div></div></div><div class="BlobViewHeader-module__Box_3__ng6v2"><div class="d-none"></div><div class="react-blob-header-edit-and-raw-actions BlobViewHeader-module__Box_4__J4Y4W"><div class="d-none"></div><div class="prc-ButtonGroup-ButtonGroup-vFUrY" data-component="ButtonGroup"><div class="prc-ButtonGroup-Item-PqvDl"><a data-component="LinkButton" href="https://github.com/github/branch-deploy/raw/refs/heads/main/docs/examples.md" data-testid="raw-button" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov BlobViewHeader-module__LinkButton__X9kx2" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Raw</span></span></a></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="copy-raw-button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_qaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_qaucpala9lik5_">Copy raw file</span></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="download-raw-button" class="prc-Button-ButtonBase-9n-Xk BlobViewHeader-module__downloadButton__ef459 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_eaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_eaucpala9lik5_">Download raw file</span></div></div></div><button data-component="IconButton" type="button" aria-pressed="false" class="prc-Button-ButtonBase-9n-Xk tmp-mr-2 TableOfContents-module__IconButton__jrlNM prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_3ucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_3ucpala9lik5_">Outline</span><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click BlobViewHeader-module__IconButton__XrMQY prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_fkecpala9lik5_" id="_R_kecpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_fkecpala9lik5_">Edit and raw actions</span></div></div></div></div><div></div></div><div class="BlobViewContent-module__blobContentWrapper__JS0W6"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="BlobContent-module__blobContentSection__VOgZq BlobContent-module__blobContentSectionMarkdown__mPLOK" style="margin-top:46px"><div class="js-snippet-clipboard-copy-unpositioned BlobContent-module__markdownBlob__T8jpG" data-hpc="true" containertiming="hpc"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Examples</h1><a id="user-content-examples" class="anchor" aria-label="Permalink: Examples" href="#examples"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This section contains real world and common examples of how you could use this Action</p>
<blockquote>
<p dir="auto">Note: In all examples, we will be using <code>uses: github/branch-deploy@vX.X.X</code>. Replace <code>X.X.X</code> with the <a href="https://github.com/marketplace/actions/branch-deploy">latest version</a> of this Action</p>
</blockquote>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Table of Contents</h2><a id="user-content-table-of-contents" class="anchor" aria-label="Permalink: Table of Contents" href="#table-of-contents"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Quick links below to jump to a specific branch-deploy example:</p>
<ul dir="auto">
<li><a href="#examples">Examples</a>
<ul dir="auto">
<li><a href="#table-of-contents">Table of Contents</a></li>
<li><a href="#simple-example">Simple Example</a></li>
<li><a href="#terraform">Terraform</a></li>
<li><a href="#terraform-with-trusted-checkouts">Terraform with Trusted Checkouts</a></li>
<li><a href="#heroku">Heroku</a></li>
<li><a href="#railway">Railway</a></li>
<li><a href="#ssh">SSH</a></li>
<li><a href="#cloudflare-pages">Cloudflare Pages</a></li>
<li><a href="#cloudflare-workers">Cloudflare Workers</a></li>
<li><a href="#multiple-jobs">Multiple Jobs</a></li>
<li><a href="#multiple-jobs-with-github-pages-and-hugo">Multiple Jobs with GitHub Pages and Hugo</a></li>
<li><a href="#multiple-jobs-with-github-pages-and-astro">Multiple Jobs with GitHub Pages and Astro</a></li>
<li><a href="#multiple-jobs-with-github-environments">Multiple Jobs with GitHub Environments</a></li>
</ul>
</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Simple Example</h2><a id="user-content-simple-example" class="anchor" aria-label="Permalink: Simple Example" href="#simple-example"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This is the simplest possible example of how you could use the branch-deploy Action for reference</p>
<ul dir="auto">
<li><code>.noop</code> will run the noop deploy step only (you can configure noop deployments however you like, this is just an example)</li>
<li><code>.deploy</code> will deploy the current branch via the deploy step only (you can configure deployments however you like, this is just an example)</li>
</ul>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments

    steps:
      # The branch-deploy Action
      - name: branch-deploy
        id: branch-deploy
        uses: github/branch-deploy@vX.X.X

        # If the branch-deploy Action was triggered, checkout our branch
      - uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          persist-credentials: false

        # If the branch-deploy Action was triggered, run the noop deployment (i.e. '.noop')
      - name: noop deploy
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}
        run: &lt;do-your-noop-deployment&gt; # this could be anything you want

        # If the branch-deploy Action was triggered, run the real deployment (i.e. '.deploy')
      - name: deploy
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}
        run: &lt;do-your-deployment&gt; # this could be anything you want"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-c"><span class="pl-c">#</span> Permissions needed for reacting and adding comments for IssueOps commands</span>
<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">name</span>: <span class="pl-s">deploy</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> The branch-deploy Action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, checkout our branch</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, run the noop deployment (i.e. '.noop')</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">noop deploy</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">&lt;do-your-noop-deployment&gt; </span><span class="pl-c"><span class="pl-c">#</span> this could be anything you want</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, run the real deployment (i.e. '.deploy')</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">deploy</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">&lt;do-your-deployment&gt; </span><span class="pl-c"><span class="pl-c">#</span> this could be anything you want</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Terraform</h2><a id="user-content-terraform" class="anchor" aria-label="Permalink: Terraform" href="#terraform"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This example shows how you could use this Action with <a href="https://www.terraform.io/" rel="nofollow">Terraform</a></p>
<ul dir="auto">
<li><code>.noop</code> triggers a Terraform plan</li>
<li><code>.deploy</code> triggers a Terraform apply</li>
</ul>
<p dir="auto">All deployment results get posted as a comment in the branch deploy output on your pull request</p>
<blockquote>
<p dir="auto">A live example can be found <a href="https://github.com/the-hideout/cloudflare/blob/3f3adedb729b9aba0cc324a161ad8ddd6f56141b/.github/workflows/branch-deploy.yml">here</a></p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

# The working directory where our Terraform files are located
env:
  WORKING_DIR: terraform/

# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments
    environment: production-secrets # the locked down environment we pull secrets from
    defaults:
      run:
        working-directory: ${{ env.WORKING_DIR }} # the directory we use where all our TF files are stored

    steps:
      # The branch-deploy Action
      - name: branch-deploy
        id: branch-deploy
        uses: github/branch-deploy@vX.X.X

        # If the branch-deploy Action was triggered, checkout our branch
      - name: Checkout
        if: steps.branch-deploy.outputs.continue == 'true'
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          persist-credentials: false

        # Setup Terraform on our Actions runner
      - uses: hashicorp/setup-terraform@ed3a0531877aca392eb870f440d9ae7aba83a6bd # pin@v1
        if: steps.branch-deploy.outputs.continue == 'true'
        with:
          terraform_version: 1.1.7 # use the version of Terraform your project uses here
          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}

        # Run Terraform init in our working directory
      - name: Terraform init
        if: steps.branch-deploy.outputs.continue == 'true'
        run: terraform init

        # If '.noop' was used, run a Terraform plan
      - name: Terraform plan
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}
        id: plan
        run: terraform plan -no-color
        continue-on-error: true # continue on error as we will handle errors later on

        # If '.deploy' was used, run a Terraform apply
      - name: Terraform apply
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}
        id: apply
        run: terraform apply -no-color -auto-approve
        continue-on-error: true # continue on error as we will handle errors later on

        # This step writes the TF plan/apply output to $GITHUB_ENV which the branch-deploy Action will read from and post as a comment on the pull request
      - name: Terraform plan output
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}
        env:
          TF_STDOUT: ${{ steps.plan.outputs.stdout }}
        run: |
          delimiter=&quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')&quot;
          while printf '%s\n' &quot;$TF_STDOUT&quot; | grep -Fxq &quot;$delimiter&quot;; do
            delimiter=&quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')&quot;
          done
          {
            printf 'DEPLOY_MESSAGE&lt;&lt;%s\n' &quot;$delimiter&quot;
            printf '%s\n' '```terraform'
            printf '%s\n' &quot;$TF_STDOUT&quot;
            printf '%s\n' '```'
            printf '%s\n' &quot;$delimiter&quot;
          } &gt;&gt; &quot;$GITHUB_ENV&quot;

      - name: Terraform apply output
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}
        env:
          TF_STDOUT: ${{ steps.apply.outputs.stdout }}
        run: |
          delimiter=&quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')&quot;
          while printf '%s\n' &quot;$TF_STDOUT&quot; | grep -Fxq &quot;$delimiter&quot;; do
            delimiter=&quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')&quot;
          done
          {
            printf 'DEPLOY_MESSAGE&lt;&lt;%s\n' &quot;$delimiter&quot;
            printf '%s\n' '```terraform'
            printf '%s\n' &quot;$TF_STDOUT&quot;
            printf '%s\n' '```'
            printf '%s\n' &quot;$delimiter&quot;
          } &gt;&gt; &quot;$GITHUB_ENV&quot;

        # Here we handle any errors that might have occurred during the Terraform plan/apply and exit accordingly
      - name: Check Terraform plan output
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' &amp;&amp; steps.plan.outcome == 'failure' }}
        run: exit 1
      - name: Check Terraform apply output
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.apply.outcome == 'failure' }}
        run: exit 1"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-c"><span class="pl-c">#</span> The working directory where our Terraform files are located</span>
<span class="pl-ent">env</span>:
  <span class="pl-ent">WORKING_DIR</span>: <span class="pl-s">terraform/</span>

<span class="pl-c"><span class="pl-c">#</span> Permissions needed for reacting and adding comments for IssueOps commands</span>
<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">name</span>: <span class="pl-s">deploy</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>
    <span class="pl-ent">environment</span>: <span class="pl-s">production-secrets </span><span class="pl-c"><span class="pl-c">#</span> the locked down environment we pull secrets from</span>
    <span class="pl-ent">defaults</span>:
      <span class="pl-ent">run</span>:
        <span class="pl-ent">working-directory</span>: <span class="pl-s">${{ env.WORKING_DIR }} </span><span class="pl-c"><span class="pl-c">#</span> the directory we use where all our TF files are stored</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> The branch-deploy Action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, checkout our branch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
        <span class="pl-ent">if</span>: <span class="pl-s">steps.branch-deploy.outputs.continue == 'true'</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

        <span class="pl-c"><span class="pl-c">#</span> Setup Terraform on our Actions runner</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">hashicorp/setup-terraform@ed3a0531877aca392eb870f440d9ae7aba83a6bd </span><span class="pl-c"><span class="pl-c">#</span> pin@v1</span>
        <span class="pl-ent">if</span>: <span class="pl-s">steps.branch-deploy.outputs.continue == 'true'</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">terraform_version</span>: <span class="pl-s">1.1.7 </span><span class="pl-c"><span class="pl-c">#</span> use the version of Terraform your project uses here</span>
          <span class="pl-ent">cli_config_credentials_token</span>: <span class="pl-s">${{ secrets.TF_API_TOKEN }}</span>

        <span class="pl-c"><span class="pl-c">#</span> Run Terraform init in our working directory</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Terraform init</span>
        <span class="pl-ent">if</span>: <span class="pl-s">steps.branch-deploy.outputs.continue == 'true'</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform init</span>

        <span class="pl-c"><span class="pl-c">#</span> If '.noop' was used, run a Terraform plan</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Terraform plan</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}</span>
        <span class="pl-ent">id</span>: <span class="pl-s">plan</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform plan -no-color</span>
        <span class="pl-ent">continue-on-error</span>: <span class="pl-s">true </span><span class="pl-c"><span class="pl-c">#</span> continue on error as we will handle errors later on</span>

        <span class="pl-c"><span class="pl-c">#</span> If '.deploy' was used, run a Terraform apply</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Terraform apply</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}</span>
        <span class="pl-ent">id</span>: <span class="pl-s">apply</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform apply -no-color -auto-approve</span>
        <span class="pl-ent">continue-on-error</span>: <span class="pl-s">true </span><span class="pl-c"><span class="pl-c">#</span> continue on error as we will handle errors later on</span>

        <span class="pl-c"><span class="pl-c">#</span> This step writes the TF plan/apply output to $GITHUB_ENV which the branch-deploy Action will read from and post as a comment on the pull request</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Terraform plan output</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">TF_STDOUT</span>: <span class="pl-s">${{ steps.plan.outputs.stdout }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          delimiter="branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')"</span>
<span class="pl-s">          while printf '%s\n' "$TF_STDOUT" | grep -Fxq "$delimiter"; do</span>
<span class="pl-s">            delimiter="branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')"</span>
<span class="pl-s">          done</span>
<span class="pl-s">          {</span>
<span class="pl-s">            printf 'DEPLOY_MESSAGE&lt;&lt;%<span class="pl-s1">s\n' "$delimiter"</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' '```terraform'</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' "$TF_STDOUT"</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' '```'</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' "$delimiter"</span></span>
<span class="pl-s"><span class="pl-s1">          } &gt;&gt; "$GITHUB_ENV"</span></span>
<span class="pl-s"><span class="pl-s1"></span></span>
<span class="pl-s"><span class="pl-s1">      - name: Terraform apply output</span></span>
<span class="pl-s"><span class="pl-s1">        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}</span></span>
<span class="pl-s"><span class="pl-s1">        env:</span></span>
<span class="pl-s"><span class="pl-s1">          TF_STDOUT: ${{ steps.apply.outputs.stdout }}</span></span>
<span class="pl-s"><span class="pl-s1">        run: |</span></span>
<span class="pl-s"><span class="pl-s1">          delimiter="branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')"</span></span>
<span class="pl-s"><span class="pl-s1">          while printf '%s\n' "$TF_STDOUT" | grep -Fxq "$delimiter"; do</span></span>
<span class="pl-s"><span class="pl-s1">            delimiter="branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')"</span></span>
<span class="pl-s"><span class="pl-s1">          done</span></span>
<span class="pl-s"><span class="pl-s1">          {</span></span>
<span class="pl-s"><span class="pl-s1">            printf 'DEPLOY_MESSAGE&lt;&lt;%s\n' "$delimiter"</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' '```terraform'</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' "$TF_STDOUT"</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' '```'</span></span>
<span class="pl-s"><span class="pl-s1">            printf '%s\n' "$delimiter"</span></span>
<span class="pl-s"><span class="pl-s1">          } &gt;&gt; "$GITHUB_ENV"</span></span>
<span class="pl-s"><span class="pl-s1"></span></span>
<span class="pl-s"><span class="pl-s1">        # Here we handle any errors that might have occurred during the Terraform plan/apply and exit accordingly</span></span>
<span class="pl-s"><span class="pl-s1">      - name: Check Terraform plan output</span></span>
<span class="pl-s"><span class="pl-s1">        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' &amp;&amp; steps.plan.outcome == 'failure' }}</span></span>
<span class="pl-s"><span class="pl-s1">        run: exit 1</span></span>
<span class="pl-s"><span class="pl-s1">      - name: Check Terraform apply output</span></span>
<span class="pl-s"><span class="pl-s1">        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.apply.outcome == 'failure' }}</span></span>
<span class="pl-s"><span class="pl-s1">        run: exit 1</span></span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Terraform with Trusted Checkouts</h2><a id="user-content-terraform-with-trusted-checkouts" class="anchor" aria-label="Permalink: Terraform with Trusted Checkouts" href="#terraform-with-trusted-checkouts"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This example shows a hardened Terraform setup that separates trusted deployment
helper code from the working pull request code selected by branch-deploy.</p>
<ul dir="auto">
<li><code>.noop</code> runs <code>terraform plan</code> from the exact working commit SHA selected by branch-deploy</li>
<li><code>.deploy</code> runs <code>terraform apply</code> from that same working commit SHA</li>
<li>the deployment message template is fetched by Branch Deploy at the exact trusted workflow SHA</li>
<li>Terraform output is captured in <code>RUNNER_TEMP</code> and exported through <code>DEPLOY_MESSAGE</code></li>
<li>merge deploy mode avoids redeploying a default-branch commit only when the newest relevant Branch Deploy deployment is active and has the same commit tree</li>
<li>unlock-on-merge mode cleans up sticky locks after the pull request merges</li>
</ul>
<p dir="auto">For the general security model behind this pattern, see the
<a href="/github/branch-deploy/blob/main/docs/trusted-checkouts.md">trusted checkout hardening guide</a>.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto"><code>.github/workflows/branch-deploy.yml</code></h3><a id="user-content-githubworkflowsbranch-deployyml" class="anchor" aria-label="Permalink: .github/workflows/branch-deploy.yml" href="#githubworkflowsbranch-deployyml"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

env:
  TF_IN_AUTOMATION: &quot;true&quot;

jobs:
  branch-deploy:
    if:
      ${{ github.event.issue.pull_request &amp;&amp;
      (startsWith(github.event.comment.body, '.deploy') ||
      startsWith(github.event.comment.body, '.noop') ||
      startsWith(github.event.comment.body, '.lock') ||
      startsWith(github.event.comment.body, '.help') ||
      startsWith(github.event.comment.body, '.wcid') ||
      startsWith(github.event.comment.body, '.unlock')) }}
    runs-on: ubuntu-latest
    environment:
      name: production
      deployment: false
    concurrency:
      group: ${{ (startsWith(github.event.comment.body, '.deploy') || startsWith(github.event.comment.body, '.noop')) &amp;&amp; 'terraform-production' || format('branch-deploy-support-{0}', github.run_id) }}
      cancel-in-progress: false
      queue: max

    steps:
      - name: branch-deploy
        id: branch-deploy
        uses: github/branch-deploy@vX.X.X
        with:
          trigger: &quot;.deploy&quot;
          sticky_locks: true
          deployment_confirmation: true
          deploy_message_path: .github/deployment_message.md
          allow_forks: false

      - name: derive working checkout path
        id: working-path
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          DEPLOY_SHA: ${{ steps.branch-deploy.outputs.sha }}
        run: |
          set -euo pipefail
          echo &quot;DEPLOY_SHA=${DEPLOY_SHA}&quot;

          if [[ ! &quot;${DEPLOY_SHA}&quot; =~ ^[0-9a-fA-F]{40}([0-9a-fA-F]{24})?$ ]]; then
            echo &quot;invalid branch-deploy sha output: ${DEPLOY_SHA}&quot; &gt;&amp;2
            exit 1
          fi

          working_dir=&quot;deployment-${DEPLOY_SHA}&quot;

          echo &quot;working_dir=${working_dir}&quot; &gt;&gt; &quot;${GITHUB_OUTPUT}&quot;
          echo &quot;working checkout directory: ${working_dir}&quot;

      - name: checkout working deployment sha
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          path: ${{ steps.working-path.outputs.working_dir }}
          fetch-depth: 1
          persist-credentials: false

      - name: verify checkout provenance
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          WORKING_DIR: ${{ steps.working-path.outputs.working_dir }}
          WORKING_SHA: ${{ steps.branch-deploy.outputs.sha }}
        run: |
          set -euo pipefail

          working_head=&quot;$(git -C &quot;${WORKING_DIR}&quot; rev-parse HEAD)&quot;

          if [[ &quot;${working_head}&quot; != &quot;${WORKING_SHA}&quot; ]]; then
            echo &quot;working checkout HEAD mismatch: expected ${WORKING_SHA}, got ${working_head}&quot; &gt;&amp;2
            exit 1
          fi

          echo &quot;working checkout: ${WORKING_DIR}@${working_head}&quot;

      - name: prepare terraform output path
        id: terraform-output
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        run: |
          set -euo pipefail

          output_dir=&quot;$(mktemp -d &quot;${RUNNER_TEMP}/branch-deploy-output.XXXXXX&quot;)&quot;
          output_path=&quot;${output_dir}/terraform-output.txt&quot;
          : &gt; &quot;${output_path}&quot;

          if [[ -L &quot;${output_path}&quot; || ! -f &quot;${output_path}&quot; ]]; then
            echo &quot;terraform output path is not a regular file: ${output_path}&quot; &gt;&amp;2
            exit 1
          fi

          echo &quot;path=${output_path}&quot; &gt;&gt; &quot;${GITHUB_OUTPUT}&quot;
          echo &quot;terraform output path: ${output_path}&quot;

      - name: read terraform version
        id: terraform-version
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform
        run: echo &quot;version=$(cat .terraform-version)&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;

      - name: setup terraform
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        uses: hashicorp/setup-terraform@v4
        with:
          terraform_version: ${{ steps.terraform-version.outputs.version }}

      - name: terraform init
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform
        env:
          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}
        run: terraform init

      - name: terraform plan
        id: plan
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}
        continue-on-error: true
        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform
        env:
          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}
          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}
        run: |
          set -o pipefail
          terraform plan -no-color -compact-warnings | tee &quot;$TERRAFORM_OUTPUT_PATH&quot;

      - name: terraform apply
        id: apply
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}
        continue-on-error: true
        working-directory: ${{ steps.working-path.outputs.working_dir }}/terraform
        env:
          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}
          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}
        run: |
          set -o pipefail
          terraform apply -auto-approve -no-color -compact-warnings | tee &quot;$TERRAFORM_OUTPUT_PATH&quot;

      - name: verify terraform output capture
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          TERRAFORM_OUTPUT_PATH: ${{ steps.terraform-output.outputs.path }}
        run: |
          set -euo pipefail

          if [[ -L &quot;${TERRAFORM_OUTPUT_PATH}&quot; || ! -f &quot;${TERRAFORM_OUTPUT_PATH}&quot; ]]; then
            echo &quot;terraform output path is not a regular file: ${TERRAFORM_OUTPUT_PATH}&quot; &gt;&amp;2
            exit 1
          fi

      - name: export deploy message
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          RESULTS_PATH: ${{ steps.terraform-output.outputs.path }}
        run: |
          set -euo pipefail
          delimiter=&quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')&quot;
          while grep -Fxq &quot;${delimiter}&quot; &quot;${RESULTS_PATH}&quot;; do
            delimiter=&quot;branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')&quot;
          done
          {
            printf 'DEPLOY_MESSAGE&lt;&lt;%s\n' &quot;${delimiter}&quot;
            cat &quot;${RESULTS_PATH}&quot;
            printf '\n%s\n' &quot;${delimiter}&quot;
          } &gt;&gt; &quot;${GITHUB_ENV}&quot;

      - name: check terraform plan
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' &amp;&amp; steps.plan.outcome == 'failure' }}
        run: exit 1

      - name: check terraform apply
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.apply.outcome == 'failure' }}
        run: exit 1"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">env</span>:
  <span class="pl-ent">TF_IN_AUTOMATION</span>: <span class="pl-s"><span class="pl-pds">"</span>true<span class="pl-pds">"</span></span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">branch-deploy</span>:
    <span class="pl-ent">if</span>:
      <span class="pl-s">${{ github.event.issue.pull_request &amp;&amp;</span>
      <span class="pl-s">(startsWith(github.event.comment.body, '.deploy') ||</span>
      <span class="pl-s">startsWith(github.event.comment.body, '.noop') ||</span>
      <span class="pl-s">startsWith(github.event.comment.body, '.lock') ||</span>
      <span class="pl-s">startsWith(github.event.comment.body, '.help') ||</span>
      <span class="pl-s">startsWith(github.event.comment.body, '.wcid') ||</span>
      <span class="pl-s">startsWith(github.event.comment.body, '.unlock')) }}</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">environment</span>:
      <span class="pl-ent">name</span>: <span class="pl-s">production</span>
      <span class="pl-ent">deployment</span>: <span class="pl-c1">false</span>
    <span class="pl-ent">concurrency</span>:
      <span class="pl-ent">group</span>: <span class="pl-s">${{ (startsWith(github.event.comment.body, '.deploy') || startsWith(github.event.comment.body, '.noop')) &amp;&amp; 'terraform-production' || format('branch-deploy-support-{0}', github.run_id) }}</span>
      <span class="pl-ent">cancel-in-progress</span>: <span class="pl-c1">false</span>
      <span class="pl-ent">queue</span>: <span class="pl-s">max</span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">trigger</span>: <span class="pl-s"><span class="pl-pds">"</span>.deploy<span class="pl-pds">"</span></span>
          <span class="pl-ent">sticky_locks</span>: <span class="pl-c1">true</span>
          <span class="pl-ent">deployment_confirmation</span>: <span class="pl-c1">true</span>
          <span class="pl-ent">deploy_message_path</span>: <span class="pl-s">.github/deployment_message.md</span>
          <span class="pl-ent">allow_forks</span>: <span class="pl-c1">false</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">derive working checkout path</span>
        <span class="pl-ent">id</span>: <span class="pl-s">working-path</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">DEPLOY_SHA</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          set -euo pipefail</span>
<span class="pl-s">          echo "DEPLOY_SHA=${DEPLOY_SHA}"</span>
<span class="pl-s"></span>
<span class="pl-s">          if [[ ! "${DEPLOY_SHA}" =~ ^[0-9a-fA-F]{40}([0-9a-fA-F]{24})?$ ]]; then</span>
<span class="pl-s">            echo "invalid branch-deploy sha output: ${DEPLOY_SHA}" &gt;&amp;2</span>
<span class="pl-s">            exit 1</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          working_dir="deployment-${DEPLOY_SHA}"</span>
<span class="pl-s"></span>
<span class="pl-s">          echo "working_dir=${working_dir}" &gt;&gt; "${GITHUB_OUTPUT}"</span>
<span class="pl-s">          echo "working checkout directory: ${working_dir}"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      - <span class="pl-ent">name</span>: <span class="pl-s">checkout working deployment sha</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">path</span>: <span class="pl-s">${{ steps.working-path.outputs.working_dir }}</span>
          <span class="pl-ent">fetch-depth</span>: <span class="pl-c1">1</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">verify checkout provenance</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">WORKING_DIR</span>: <span class="pl-s">${{ steps.working-path.outputs.working_dir }}</span>
          <span class="pl-ent">WORKING_SHA</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          set -euo pipefail</span>
<span class="pl-s"></span>
<span class="pl-s">          working_head="$(git -C "${WORKING_DIR}" rev-parse HEAD)"</span>
<span class="pl-s"></span>
<span class="pl-s">          if [[ "${working_head}" != "${WORKING_SHA}" ]]; then</span>
<span class="pl-s">            echo "working checkout HEAD mismatch: expected ${WORKING_SHA}, got ${working_head}" &gt;&amp;2</span>
<span class="pl-s">            exit 1</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          echo "working checkout: ${WORKING_DIR}@${working_head}"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      - <span class="pl-ent">name</span>: <span class="pl-s">prepare terraform output path</span>
        <span class="pl-ent">id</span>: <span class="pl-s">terraform-output</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          set -euo pipefail</span>
<span class="pl-s"></span>
<span class="pl-s">          output_dir="$(mktemp -d "${RUNNER_TEMP}/branch-deploy-output.XXXXXX")"</span>
<span class="pl-s">          output_path="${output_dir}/terraform-output.txt"</span>
<span class="pl-s">          : &gt; "${output_path}"</span>
<span class="pl-s"></span>
<span class="pl-s">          if [[ -L "${output_path}" || ! -f "${output_path}" ]]; then</span>
<span class="pl-s">            echo "terraform output path is not a regular file: ${output_path}" &gt;&amp;2</span>
<span class="pl-s">            exit 1</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          echo "path=${output_path}" &gt;&gt; "${GITHUB_OUTPUT}"</span>
<span class="pl-s">          echo "terraform output path: ${output_path}"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      - <span class="pl-ent">name</span>: <span class="pl-s">read terraform version</span>
        <span class="pl-ent">id</span>: <span class="pl-s">terraform-version</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">working-directory</span>: <span class="pl-s">${{ steps.working-path.outputs.working_dir }}/terraform</span>
        <span class="pl-ent">run</span>: <span class="pl-s">echo "version=$(cat .terraform-version)" &gt;&gt; "$GITHUB_OUTPUT"</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">setup terraform</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">hashicorp/setup-terraform@v4</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">terraform_version</span>: <span class="pl-s">${{ steps.terraform-version.outputs.version }}</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">terraform init</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">working-directory</span>: <span class="pl-s">${{ steps.working-path.outputs.working_dir }}/terraform</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">TF_TOKEN_app_terraform_io</span>: <span class="pl-s">${{ secrets.TF_API_TOKEN }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform init</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">terraform plan</span>
        <span class="pl-ent">id</span>: <span class="pl-s">plan</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' }}</span>
        <span class="pl-ent">continue-on-error</span>: <span class="pl-c1">true</span>
        <span class="pl-ent">working-directory</span>: <span class="pl-s">${{ steps.working-path.outputs.working_dir }}/terraform</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">TF_TOKEN_app_terraform_io</span>: <span class="pl-s">${{ secrets.TF_API_TOKEN }}</span>
          <span class="pl-ent">TERRAFORM_OUTPUT_PATH</span>: <span class="pl-s">${{ steps.terraform-output.outputs.path }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          set -o pipefail</span>
<span class="pl-s">          terraform plan -no-color -compact-warnings | tee "$TERRAFORM_OUTPUT_PATH"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      - <span class="pl-ent">name</span>: <span class="pl-s">terraform apply</span>
        <span class="pl-ent">id</span>: <span class="pl-s">apply</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}</span>
        <span class="pl-ent">continue-on-error</span>: <span class="pl-c1">true</span>
        <span class="pl-ent">working-directory</span>: <span class="pl-s">${{ steps.working-path.outputs.working_dir }}/terraform</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">TF_TOKEN_app_terraform_io</span>: <span class="pl-s">${{ secrets.TF_API_TOKEN }}</span>
          <span class="pl-ent">TERRAFORM_OUTPUT_PATH</span>: <span class="pl-s">${{ steps.terraform-output.outputs.path }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          set -o pipefail</span>
<span class="pl-s">          terraform apply -auto-approve -no-color -compact-warnings | tee "$TERRAFORM_OUTPUT_PATH"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      - <span class="pl-ent">name</span>: <span class="pl-s">verify terraform output capture</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">TERRAFORM_OUTPUT_PATH</span>: <span class="pl-s">${{ steps.terraform-output.outputs.path }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          set -euo pipefail</span>
<span class="pl-s"></span>
<span class="pl-s">          if [[ -L "${TERRAFORM_OUTPUT_PATH}" || ! -f "${TERRAFORM_OUTPUT_PATH}" ]]; then</span>
<span class="pl-s">            echo "terraform output path is not a regular file: ${TERRAFORM_OUTPUT_PATH}" &gt;&amp;2</span>
<span class="pl-s">            exit 1</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      - <span class="pl-ent">name</span>: <span class="pl-s">export deploy message</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">RESULTS_PATH</span>: <span class="pl-s">${{ steps.terraform-output.outputs.path }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          set -euo pipefail</span>
<span class="pl-s">          delimiter="branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')"</span>
<span class="pl-s">          while grep -Fxq "${delimiter}" "${RESULTS_PATH}"; do</span>
<span class="pl-s">            delimiter="branch_deploy_$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')"</span>
<span class="pl-s">          done</span>
<span class="pl-s">          {</span>
<span class="pl-s">            printf 'DEPLOY_MESSAGE&lt;&lt;%<span class="pl-s1">s\n' "${delimiter}"</span></span>
<span class="pl-s"><span class="pl-s1">            cat "${RESULTS_PATH}"</span></span>
<span class="pl-s"><span class="pl-s1">            printf '\n%s\n' "${delimiter}"</span></span>
<span class="pl-s"><span class="pl-s1">          } &gt;&gt; "${GITHUB_ENV}"</span></span>
<span class="pl-s"><span class="pl-s1"></span></span>
<span class="pl-s"><span class="pl-s1">      - name: check terraform plan</span></span>
<span class="pl-s"><span class="pl-s1">        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop == 'true' &amp;&amp; steps.plan.outcome == 'failure' }}</span></span>
<span class="pl-s"><span class="pl-s1">        run: exit 1</span></span>
<span class="pl-s"><span class="pl-s1"></span></span>
<span class="pl-s"><span class="pl-s1">      - name: check terraform apply</span></span>
<span class="pl-s"><span class="pl-s1">        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.apply.outcome == 'failure' }}</span></span>
<span class="pl-s"><span class="pl-s1">        run: exit 1</span></span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto"><code>.github/workflows/deploy.yml</code></h3><a id="user-content-githubworkflowsdeployyml" class="anchor" aria-label="Permalink: .github/workflows/deploy.yml" href="#githubworkflowsdeployyml"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: deploy

on:
  push:
    branches: [&quot;main&quot;]

permissions:
  contents: read
  deployments: write

jobs:
  deployment-check:
    runs-on: ubuntu-latest
    outputs:
      continue: ${{ steps.deployment-check.outputs.continue }}
      sha: ${{ steps.deployment-check.outputs.sha }}

    steps:
      - name: deployment check
        id: deployment-check
        uses: github/branch-deploy@vX.X.X
        with:
          merge_deploy_mode: true
          environment: production

  deploy:
    if: ${{ needs.deployment-check.outputs.continue == 'true' }}
    needs: deployment-check
    runs-on: ubuntu-latest
    concurrency:
      group: terraform-production
      cancel-in-progress: false
      queue: max
    environment: production
    defaults:
      run:
        working-directory: terraform/
    env:
      TF_IN_AUTOMATION: &quot;true&quot;

    steps:
      - name: checkout
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ needs.deployment-check.outputs.sha }}
          fetch-depth: 1
          persist-credentials: false

      - name: read terraform version
        id: terraform-version
        working-directory: .
        run: echo &quot;version=$(cat terraform/.terraform-version)&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;

      - name: setup terraform
        uses: hashicorp/setup-terraform@v4
        with:
          terraform_version: ${{ steps.terraform-version.outputs.version }}

      - name: terraform init
        env:
          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}
        run: terraform init

      - name: terraform apply
        env:
          TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}
        run: terraform apply -auto-approve -no-color -compact-warnings"><pre><span class="pl-ent">name</span>: <span class="pl-s">deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">push</span>:
    <span class="pl-ent">branches</span>: <span class="pl-s">["main"]</span>

<span class="pl-ent">permissions</span>:
  <span class="pl-ent">contents</span>: <span class="pl-s">read</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deployment-check</span>:
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">outputs</span>:
      <span class="pl-ent">continue</span>: <span class="pl-s">${{ steps.deployment-check.outputs.continue }}</span>
      <span class="pl-ent">sha</span>: <span class="pl-s">${{ steps.deployment-check.outputs.sha }}</span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">deployment check</span>
        <span class="pl-ent">id</span>: <span class="pl-s">deployment-check</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">merge_deploy_mode</span>: <span class="pl-c1">true</span>
          <span class="pl-ent">environment</span>: <span class="pl-s">production</span>

  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.deployment-check.outputs.continue == 'true' }}</span>
    <span class="pl-ent">needs</span>: <span class="pl-s">deployment-check</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">concurrency</span>:
      <span class="pl-ent">group</span>: <span class="pl-s">terraform-production</span>
      <span class="pl-ent">cancel-in-progress</span>: <span class="pl-c1">false</span>
      <span class="pl-ent">queue</span>: <span class="pl-s">max</span>
    <span class="pl-ent">environment</span>: <span class="pl-s">production</span>
    <span class="pl-ent">defaults</span>:
      <span class="pl-ent">run</span>:
        <span class="pl-ent">working-directory</span>: <span class="pl-s">terraform/</span>
    <span class="pl-ent">env</span>:
      <span class="pl-ent">TF_IN_AUTOMATION</span>: <span class="pl-s"><span class="pl-pds">"</span>true<span class="pl-pds">"</span></span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">checkout</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ needs.deployment-check.outputs.sha }}</span>
          <span class="pl-ent">fetch-depth</span>: <span class="pl-c1">1</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">read terraform version</span>
        <span class="pl-ent">id</span>: <span class="pl-s">terraform-version</span>
        <span class="pl-ent">working-directory</span>: <span class="pl-s">.</span>
        <span class="pl-ent">run</span>: <span class="pl-s">echo "version=$(cat terraform/.terraform-version)" &gt;&gt; "$GITHUB_OUTPUT"</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">setup terraform</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">hashicorp/setup-terraform@v4</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">terraform_version</span>: <span class="pl-s">${{ steps.terraform-version.outputs.version }}</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">terraform init</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">TF_TOKEN_app_terraform_io</span>: <span class="pl-s">${{ secrets.TF_API_TOKEN }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform init</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">terraform apply</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">TF_TOKEN_app_terraform_io</span>: <span class="pl-s">${{ secrets.TF_API_TOKEN }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform apply -auto-approve -no-color -compact-warnings</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto"><code>.github/workflows/unlock-on-merge.yml</code></h3><a id="user-content-githubworkflowsunlock-on-mergeyml" class="anchor" aria-label="Permalink: .github/workflows/unlock-on-merge.yml" href="#githubworkflowsunlock-on-mergeyml"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: Unlock On Merge

on:
  pull_request:
    types: [closed]

permissions:
  contents: write

jobs:
  unlock-on-merge:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true

    steps:
      - name: unlock on merge
        id: unlock-on-merge
        uses: github/branch-deploy@vX.X.X
        with:
          unlock_on_merge_mode: true
          environment_targets: production"><pre><span class="pl-ent">name</span>: <span class="pl-s">Unlock On Merge</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">pull_request</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[closed]</span>

<span class="pl-ent">permissions</span>:
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">unlock-on-merge</span>:
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">if</span>: <span class="pl-s">github.event.pull_request.merged == true</span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">unlock on merge</span>
        <span class="pl-ent">id</span>: <span class="pl-s">unlock-on-merge</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">unlock_on_merge_mode</span>: <span class="pl-c1">true</span>
          <span class="pl-ent">environment_targets</span>: <span class="pl-s">production</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto"><code>.github/deployment_message.md</code></h3><a id="user-content-githubdeployment_messagemd" class="anchor" aria-label="Permalink: .github/deployment_message.md" href="#githubdeployment_messagemd"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-text-md notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="### Deployment Results {{ &quot;:white_check_mark:&quot; if status === &quot;success&quot; else &quot;:x:&quot; }}

{% if status === &quot;success&quot; %}**{{ actor }}** successfully **{{ &quot;noop&quot; if noop else &quot;branch&quot; }}** deployed branch `{{ ref }}` to **{{ environment }}**{% endif %}{% if status === &quot;failure&quot; %}**{{ actor }}** your **{{ &quot;noop&quot; if noop else &quot;branch&quot; }}** deployment of `{{ ref }}` failed to deploy to the **{{ environment }}** environment{% endif %}

&lt;details&gt;&lt;summary&gt;Show Results&lt;/summary&gt;

```terraform
{{ results }}
```

&lt;/details&gt;"><pre><span class="pl-mh">### <span class="pl-en">Deployment Results {{ "<span class="pl-s">:<span class="pl-k">white_check_mark</span>:</span>" if status === "success" else "<span class="pl-s">:<span class="pl-k">x</span>:</span>" }}</span></span>

{% if status === "success" %}<span class="pl-s">**</span>{{ actor }}<span class="pl-s">**</span> successfully <span class="pl-s">**</span>{{ "noop" if noop else "branch" }}<span class="pl-s">**</span> deployed branch <span class="pl-s">`</span><span class="pl-c1">{{ ref }}</span><span class="pl-s">`</span> to <span class="pl-s">**</span>{{ environment }}<span class="pl-s">**</span>{% endif %}{% if status === "failure" %}<span class="pl-s">**</span>{{ actor }}<span class="pl-s">**</span> your <span class="pl-s">**</span>{{ "noop" if noop else "branch" }}<span class="pl-s">**</span> deployment of <span class="pl-s">`</span><span class="pl-c1">{{ ref }}</span><span class="pl-s">`</span> failed to deploy to the <span class="pl-s">**</span>{{ environment }}<span class="pl-s">**</span> environment{% endif %}

&lt;<span class="pl-ent">details</span>&gt;&lt;<span class="pl-ent">summary</span>&gt;Show Results&lt;/<span class="pl-ent">summary</span>&gt;

<span class="pl-s">```</span><span class="pl-en">terraform</span><span class="pl-c1"></span>
<span class="pl-c1">{{ results }}</span>
<span class="pl-c1"></span><span class="pl-s">```</span>

&lt;/<span class="pl-ent">details</span>&gt;</pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Heroku</h2><a id="user-content-heroku" class="anchor" aria-label="Permalink: Heroku" href="#heroku"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This example shows how you could use this Action with <a href="https://heroku.com" rel="nofollow">Heroku</a></p>
<ul dir="auto">
<li><code>.noop</code> has no effect here (but you could change that)</li>
<li><code>.deploy</code> takes your current branch and deploys it to Heroku</li>
</ul>
<blockquote>
<p dir="auto">A live example can be found <a href="https://github.com/the-hideout/stash/blob/aef5a5f16b4fa6946d2eba107e7b92c5f6583c0d/.github/workflows/branch-deploy.yml">here</a></p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  deploy:
    name: deploy
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments
    runs-on: ubuntu-latest
    environment: production-secrets # the locked down environment we pull secrets from

    steps:
      # The branch-deploy Action
      - name: branch-deploy
        id: branch-deploy
        uses: github/branch-deploy@vX.X.X

        # If the branch-deploy Action was triggered, checkout our branch
      - name: Checkout
        if: steps.branch-deploy.outputs.continue == 'true'
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          persist-credentials: false

        # Deploy our branch to Heroku
      - name: Deploy to Heroku
        if: steps.branch-deploy.outputs.continue == 'true'
        uses: AkhileshNS/heroku-deploy@79ef2ae4ff9b897010907016b268fd0f88561820 # pin@v3.12.12
        with:
          heroku_app_name: &lt;your-heroku-app-name-here&gt;
          heroku_email: ${{ secrets.HEROKU_EMAIL }}
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">name</span>: <span class="pl-s">deploy</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">environment</span>: <span class="pl-s">production-secrets </span><span class="pl-c"><span class="pl-c">#</span> the locked down environment we pull secrets from</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> The branch-deploy Action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, checkout our branch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
        <span class="pl-ent">if</span>: <span class="pl-s">steps.branch-deploy.outputs.continue == 'true'</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

        <span class="pl-c"><span class="pl-c">#</span> Deploy our branch to Heroku</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Deploy to Heroku</span>
        <span class="pl-ent">if</span>: <span class="pl-s">steps.branch-deploy.outputs.continue == 'true'</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">AkhileshNS/heroku-deploy@79ef2ae4ff9b897010907016b268fd0f88561820 </span><span class="pl-c"><span class="pl-c">#</span> pin@v3.12.12</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">heroku_app_name</span>: <span class="pl-s">&lt;your-heroku-app-name-here&gt;</span>
          <span class="pl-ent">heroku_email</span>: <span class="pl-s">${{ secrets.HEROKU_EMAIL }}</span>
          <span class="pl-ent">heroku_api_key</span>: <span class="pl-s">${{ secrets.HEROKU_API_KEY }}</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Railway</h2><a id="user-content-railway" class="anchor" aria-label="Permalink: Railway" href="#railway"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This example shows how you could use this Action with <a href="https://railway.app" rel="nofollow">Railway</a></p>
<ul dir="auto">
<li><code>.noop</code> has no effect here (but you could change that)</li>
<li><code>.deploy</code> takes your current branch and deploys it to Railway</li>
</ul>
<blockquote>
<p dir="auto">A live example can be found <a href="https://github.com/the-hideout/stash/blob/ee8af01919f368f35dede3c93f703fd239dbac3c/.github/workflows/branch-deploy.yml">here</a> that has some slight modifications to the example below</p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  deploy:
    name: deploy
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments
    runs-on: ubuntu-latest
    environment: production-secrets # the locked down environment we pull secrets from

    steps:
      # The branch-deploy Action
      - name: branch-deploy
        id: branch-deploy
        uses: github/branch-deploy@vX.X.X

        # If the branch-deploy Action was triggered, checkout our branch
      - name: Checkout
        if: steps.branch-deploy.outputs.continue == 'true'
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          persist-credentials: false

        # Install the Railway CLI through npm
      - name: Install Railway
        run: npm i -g @railway/cli

        # Deploy our branch to Railway
      - name: Deploy to Railway
        if: steps.branch-deploy.outputs.continue == 'true'
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
        run: railway up"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">name</span>: <span class="pl-s">deploy</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">environment</span>: <span class="pl-s">production-secrets </span><span class="pl-c"><span class="pl-c">#</span> the locked down environment we pull secrets from</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> The branch-deploy Action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, checkout our branch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
        <span class="pl-ent">if</span>: <span class="pl-s">steps.branch-deploy.outputs.continue == 'true'</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

        <span class="pl-c"><span class="pl-c">#</span> Install the Railway CLI through npm</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Install Railway</span>
        <span class="pl-ent">run</span>: <span class="pl-s">npm i -g @railway/cli</span>

        <span class="pl-c"><span class="pl-c">#</span> Deploy our branch to Railway</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Deploy to Railway</span>
        <span class="pl-ent">if</span>: <span class="pl-s">steps.branch-deploy.outputs.continue == 'true'</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">RAILWAY_TOKEN</span>: <span class="pl-s">${{ secrets.RAILWAY_TOKEN }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">railway up</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">SSH</h2><a id="user-content-ssh" class="anchor" aria-label="Permalink: SSH" href="#ssh"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This example shows how you could use this Action with SSH</p>
<p dir="auto">You can define any commands you want to be run in your SSH Action and they would be gated by the branch-deploy Action.</p>
<ul dir="auto">
<li><code>.noop</code> has no effect here (but you could change that)</li>
<li><code>.deploy</code> runs the SSH action with your branch</li>
</ul>
<blockquote>
<p dir="auto">A live example can be found <a href="https://github.com/the-hideout/cache/blob/6ee6ee2a69104f165c9f20df6e4e5cbb337b7c54/.github/workflows/branch-deploy.yml">here</a></p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  deploy:
    environment: production-secrets # the locked down environment we pull secrets from
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments
    runs-on: ubuntu-latest

    steps:
      # The branch-deploy Action
      - uses: github/branch-deploy@vX.X.X
        id: branch-deploy

        # If the branch-deploy Action was triggered, checkout our branch
      - name: Checkout
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          persist-credentials: false

        # Deploy our branch via SSH remote commands
      - name: SSH Remote Deploy
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}
        uses: appleboy/ssh-action@4a03da89e5c43da56e502053be4bbcb293411883 # pin@v0.1.6
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          port: ${{ secrets.SSH_PORT }}
          script_stop: true
          script: &lt;run-some-ssh-commands-here&gt; # this could be whatever you want"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-c"><span class="pl-c">#</span> Permissions needed for reacting and adding comments for IssueOps commands</span>
<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">environment</span>: <span class="pl-s">production-secrets </span><span class="pl-c"><span class="pl-c">#</span> the locked down environment we pull secrets from</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> The branch-deploy Action</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, checkout our branch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

        <span class="pl-c"><span class="pl-c">#</span> Deploy our branch via SSH remote commands</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">SSH Remote Deploy</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">appleboy/ssh-action@4a03da89e5c43da56e502053be4bbcb293411883 </span><span class="pl-c"><span class="pl-c">#</span> pin@v0.1.6</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">host</span>: <span class="pl-s">${{ secrets.SSH_HOST }}</span>
          <span class="pl-ent">username</span>: <span class="pl-s">${{ secrets.SSH_USERNAME }}</span>
          <span class="pl-ent">key</span>: <span class="pl-s">${{ secrets.SSH_KEY }}</span>
          <span class="pl-ent">port</span>: <span class="pl-s">${{ secrets.SSH_PORT }}</span>
          <span class="pl-ent">script_stop</span>: <span class="pl-c1">true</span>
          <span class="pl-ent">script</span>: <span class="pl-s">&lt;run-some-ssh-commands-here&gt; </span><span class="pl-c"><span class="pl-c">#</span> this could be whatever you want</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Cloudflare Pages</h2><a id="user-content-cloudflare-pages" class="anchor" aria-label="Permalink: Cloudflare Pages" href="#cloudflare-pages"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This example shows how you could use this Action with <a href="https://pages.cloudflare.com/" rel="nofollow">Cloudflare Pages</a></p>
<ul dir="auto">
<li><code>.deploy to development</code> deploys your branch to the development environment</li>
<li><code>.deploy</code> deploys your branch to the production environment</li>
</ul>
<blockquote>
<p dir="auto">A live example can be found <a href="https://github.com/the-hideout/tarkov-dev/blob/b4417dfeb903985b83a24096b2e1ba2a22f39ddd/.github/workflows/branch-deploy.yml">here</a></p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  deploy:
    environment: secrets # the locked down environment we pull secrets from
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments
    runs-on: ubuntu-latest

    steps:
      # The branch-deploy Action
      - uses: github/branch-deploy@vX.X.X
        id: branch-deploy

        # If the branch-deploy Action was triggered, checkout our branch
      - name: Checkout
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          persist-credentials: false

        # setup node
      - uses: actions/setup-node@v4
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        with:
          node-version: '18'
          cache: 'npm'

        # Install the npm dependencies to build our cloudflare pages site
      - name: Install
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        run: npm ci

        # Build our cloudflare pages site
      - name: Build
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        run: npm run build

        # If '.deploy to development' was used, branch deploy to the development environment
      - name: deploy - dev
        id: dev-deploy
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.branch-deploy.outputs.environment == 'development' }}
        uses: cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 # pin@3.3.1
        with:
          wranglerVersion: '2.13.0' # this can be any version of wrangler you want
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          command: pages publish build/ --project-name=&lt;your-cloudflare-project-name&gt; --branch=preview

        # If '.deploy' was used, branch deploy to the production environment
      - name: deploy - prod
        id: prod-deploy
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.branch-deploy.outputs.environment == 'production' }}
        uses: cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 # pin@3.3.1
        with:
          wranglerVersion: '2.13.0' # this can be any version of wrangler you want
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          command: pages publish build/ --project-name=&lt;your-cloudflare-project-name&gt; --branch=main"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-c"><span class="pl-c">#</span> Permissions needed for reacting and adding comments for IssueOps commands</span>
<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">environment</span>: <span class="pl-s">secrets </span><span class="pl-c"><span class="pl-c">#</span> the locked down environment we pull secrets from</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> The branch-deploy Action</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, checkout our branch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

        <span class="pl-c"><span class="pl-c">#</span> setup node</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">actions/setup-node@v4</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">node-version</span>: <span class="pl-s"><span class="pl-pds">'</span>18<span class="pl-pds">'</span></span>
          <span class="pl-ent">cache</span>: <span class="pl-s"><span class="pl-pds">'</span>npm<span class="pl-pds">'</span></span>

        <span class="pl-c"><span class="pl-c">#</span> Install the npm dependencies to build our cloudflare pages site</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Install</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">npm ci</span>

        <span class="pl-c"><span class="pl-c">#</span> Build our cloudflare pages site</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Build</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">npm run build</span>

        <span class="pl-c"><span class="pl-c">#</span> If '.deploy to development' was used, branch deploy to the development environment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">deploy - dev</span>
        <span class="pl-ent">id</span>: <span class="pl-s">dev-deploy</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.branch-deploy.outputs.environment == 'development' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 </span><span class="pl-c"><span class="pl-c">#</span> pin@3.3.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">wranglerVersion</span>: <span class="pl-s"><span class="pl-pds">'</span>2.13.0<span class="pl-pds">'</span></span> <span class="pl-c"><span class="pl-c">#</span> this can be any version of wrangler you want</span>
          <span class="pl-ent">apiToken</span>: <span class="pl-s">${{ secrets.CF_API_TOKEN }}</span>
          <span class="pl-ent">accountId</span>: <span class="pl-s">${{ secrets.CF_ACCOUNT_ID }}</span>
          <span class="pl-ent">command</span>: <span class="pl-s">pages publish build/ --project-name=&lt;your-cloudflare-project-name&gt; --branch=preview</span>

        <span class="pl-c"><span class="pl-c">#</span> If '.deploy' was used, branch deploy to the production environment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">deploy - prod</span>
        <span class="pl-ent">id</span>: <span class="pl-s">prod-deploy</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp; steps.branch-deploy.outputs.noop != 'true' &amp;&amp; steps.branch-deploy.outputs.environment == 'production' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">cloudflare/wrangler-action@4b3eae832ab5113c67958be31ca062ad46c593b6 </span><span class="pl-c"><span class="pl-c">#</span> pin@3.3.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">wranglerVersion</span>: <span class="pl-s"><span class="pl-pds">'</span>2.13.0<span class="pl-pds">'</span></span> <span class="pl-c"><span class="pl-c">#</span> this can be any version of wrangler you want</span>
          <span class="pl-ent">apiToken</span>: <span class="pl-s">${{ secrets.CF_API_TOKEN }}</span>
          <span class="pl-ent">accountId</span>: <span class="pl-s">${{ secrets.CF_ACCOUNT_ID }}</span>
          <span class="pl-ent">command</span>: <span class="pl-s">pages publish build/ --project-name=&lt;your-cloudflare-project-name&gt; --branch=main</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Cloudflare Workers</h2><a id="user-content-cloudflare-workers" class="anchor" aria-label="Permalink: Cloudflare Workers" href="#cloudflare-workers"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This example shows how you could use this Action with <a href="https://workers.cloudflare.com/" rel="nofollow">Cloudflare Workers</a></p>
<ul dir="auto">
<li><code>.deploy to development</code> deploys your branch to the development environment (if you have one with your Cloudflare workers)</li>
<li><code>.deploy</code> deploys your branch to the production environment</li>
</ul>
<blockquote>
<p dir="auto">A live example can be found <a href="https://github.com/the-hideout/tarkov-api/blob/1677543951d5f2a848c2650eb3400178b8f9a55b/.github/workflows/branch-deploy.yml">here</a></p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch-deploy

on:
  issue_comment:
    types: [created]

# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  deploy:
    environment: secrets # the locked down environment we pull secrets from
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments
    runs-on: ubuntu-latest

    steps:
      # The branch-deploy Action
      - uses: github/branch-deploy@vX.X.X
        id: branch-deploy

        # If the branch-deploy Action was triggered, checkout our branch
      - name: Checkout
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ steps.branch-deploy.outputs.sha }}
          persist-credentials: false

        # Install the npm dependencies for your cloudflare workers project
        # Most importantly, we need to install @cloudflare/wrangler
      - name: Install dependencies
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        run: npm ci

        # If '.deploy to development' was used, branch deploy to the development environment
      - name: Publish - Development
        if: ${{ steps.branch-deploy.outputs.environment == 'development' &amp;&amp;
          steps.branch-deploy.outputs.noop != 'true' &amp;&amp;
          steps.branch-deploy.outputs.continue == 'true' }}
        uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # pin@2.0.0
        with:
          wranglerVersion: '2.17.0' # this can be any version of wrangler you want
          apiToken: ${{ secrets.CF_API_TOKEN }}
          environment: 'development' # here we use development

        # If '.deploy' was used, branch deploy to the production environment
      - name: Publish - Production
        if: ${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp;
          steps.branch-deploy.outputs.noop != 'true' &amp;&amp;
          steps.branch-deploy.outputs.environment == 'production' }}
        uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # pin@2.0.0
        with:
          wranglerVersion: '2.17.0' # this can be any version of wrangler you want
          apiToken: ${{ secrets.CF_API_TOKEN }}"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch-deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-c"><span class="pl-c">#</span> Permissions needed for reacting and adding comments for IssueOps commands</span>
<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">environment</span>: <span class="pl-s">secrets </span><span class="pl-c"><span class="pl-c">#</span> the locked down environment we pull secrets from</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> The branch-deploy Action</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>

        <span class="pl-c"><span class="pl-c">#</span> If the branch-deploy Action was triggered, checkout our branch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

        <span class="pl-c"><span class="pl-c">#</span> Install the npm dependencies for your cloudflare workers project</span>
        <span class="pl-c"><span class="pl-c">#</span> Most importantly, we need to install @cloudflare/wrangler</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Install dependencies</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">npm ci</span>

        <span class="pl-c"><span class="pl-c">#</span> If '.deploy to development' was used, branch deploy to the development environment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Publish - Development</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment == 'development' &amp;&amp;</span>
          <span class="pl-s">steps.branch-deploy.outputs.noop != 'true' &amp;&amp;</span>
          <span class="pl-s">steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd </span><span class="pl-c"><span class="pl-c">#</span> pin@2.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">wranglerVersion</span>: <span class="pl-s"><span class="pl-pds">'</span>2.17.0<span class="pl-pds">'</span></span> <span class="pl-c"><span class="pl-c">#</span> this can be any version of wrangler you want</span>
          <span class="pl-ent">apiToken</span>: <span class="pl-s">${{ secrets.CF_API_TOKEN }}</span>
          <span class="pl-ent">environment</span>: <span class="pl-s"><span class="pl-pds">'</span>development<span class="pl-pds">'</span></span> <span class="pl-c"><span class="pl-c">#</span> here we use development</span>

        <span class="pl-c"><span class="pl-c">#</span> If '.deploy' was used, branch deploy to the production environment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Publish - Production</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' &amp;&amp;</span>
          <span class="pl-s">steps.branch-deploy.outputs.noop != 'true' &amp;&amp;</span>
          <span class="pl-s">steps.branch-deploy.outputs.environment == 'production' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd </span><span class="pl-c"><span class="pl-c">#</span> pin@2.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">wranglerVersion</span>: <span class="pl-s"><span class="pl-pds">'</span>2.17.0<span class="pl-pds">'</span></span> <span class="pl-c"><span class="pl-c">#</span> this can be any version of wrangler you want</span>
          <span class="pl-ent">apiToken</span>: <span class="pl-s">${{ secrets.CF_API_TOKEN }}</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Multiple Jobs</h2><a id="user-content-multiple-jobs" class="anchor" aria-label="Permalink: Multiple Jobs" href="#multiple-jobs"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you need a complex deployment workflow, you can complete the deployment manually in a separate job. With <code>skip_completing: true</code>, your workflow owns final deployment statuses, comments, reactions, labels, and non-sticky lock cleanup. See <a href="https://github.com/github/branch-deploy/blob/main/README.md#manual-deployment-control">here</a> for more details.</p>
<blockquote>
<p dir="auto">This is a more advanced example</p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: deploy

on:
  issue_comment:
    types: [created]

permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

jobs:
  trigger:
    if: ${{ github.event.issue.pull_request }} # only run on pull request comments
    runs-on: ubuntu-latest
    outputs:
      continue: ${{ steps.branch-deploy.outputs.continue }}
      noop: ${{ steps.branch-deploy.outputs.noop }}
      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}
      environment: ${{ steps.branch-deploy.outputs.environment }}
      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}
      sha: ${{ steps.branch-deploy.outputs.sha }}
      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}
      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}
      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}

    steps:
      - uses: github/branch-deploy@vX.X.X
        id: branch-deploy
        with:
          trigger: &quot;.deploy&quot;
          skip_completing: true # we will complete the deployment manually

      - name: Capture deployment lock
        id: capture-lock
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
        run: |
          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          if lock_ref_sha=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}&quot; --jq '.object.sha' 2&gt;/dev/null)&quot;; then
            printf 'sha=%s\n' &quot;$lock_ref_sha&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
          else
            echo &quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped&quot;
          fi

  deploy:
    needs: trigger
    if: ${{ needs.trigger.outputs.continue == 'true' &amp;&amp; needs.trigger.outputs.noop != 'true' }}
    runs-on: ubuntu-latest

    steps:
      # checkout the project's repository based on the commit SHA provided by the branch-deploy step
      - name: checkout
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ needs.trigger.outputs.sha }}
          persist-credentials: false

      # You will do your own deployment here
      - name: fake regular deploy
        run: echo &quot;I am doing a fake regular deploy&quot;

  # update the deployment result - manually complete the deployment that was created by the branch-deploy action
  result:
    needs: [trigger, deploy]
    runs-on: ubuntu-latest
    # run even on failures but only if the trigger job set continue to true
    if: ${{ always() &amp;&amp; needs.trigger.outputs.continue == 'true' }}

    steps:
      # if a previous step failed, set a variable to use as the deployment status
      - name: set deployment status
        id: deploy-status
        if: ${{ needs.trigger.result == 'failure' || needs.deploy.result == 'failure' }}
        run: |
          echo &quot;DEPLOY_STATUS=failure&quot; &gt;&gt; $GITHUB_OUTPUT

      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action
      - name: Create a deployment status
        env:
          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}
          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}
        run: |
          if [ -z &quot;${DEPLOY_STATUS}&quot; ]; then
            DEPLOY_STATUS=&quot;success&quot;
          fi

          gh api \
            --method POST \
            &quot;repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses&quot; \
            -f environment=&quot;${ENVIRONMENT}&quot; \
            -f state=&quot;${DEPLOY_STATUS}&quot;

      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action
      - name: Remove a non-sticky lock
        env:
          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}
          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
          LOCK_ACTOR: ${{ github.actor }}
          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}
        run: |
          if [ -z &quot;${LOCK_REF_SHA}&quot; ]; then
            echo &quot;No captured deployment lock remains&quot;
            exit 0
          fi

          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          lock_contents=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}&quot; --jq '.content' | base64 --decode)&quot;
          lock_link=&quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}&quot;

          if ! printf '%s' &quot;$lock_contents&quot; | jq -e \
            --arg actor &quot;$LOCK_ACTOR&quot; \
            --arg environment &quot;$ENVIRONMENT&quot; \
            --arg link &quot;$lock_link&quot; \
            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then
            echo &quot;The captured deployment lock is sticky or belongs to another deployment&quot;
            exit 0
          fi

          repository_id=&quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')&quot;
          if gh api graphql \
            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: &quot;0000000000000000000000000000000000000000&quot;}]}) { clientMutationId } }' \
            -f repository=&quot;$repository_id&quot; \
            -f name=&quot;refs/heads/${lock_branch}&quot; \
            -f before=&quot;$LOCK_REF_SHA&quot; &gt;/dev/null; then
            echo &quot;Removed the original deployment lock&quot;
          else
            echo &quot;::warning::The original deployment lock changed; leaving the current lock in place&quot;
          fi

      # remove the default 'eyes' reaction from the comment that triggered the deployment
      # this reaction is added by the branch-deploy action by default
      - name: remove eyes reaction
        env:
          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}
        run: |
          if [ -n &quot;${INITIAL_REACTION_ID}&quot; ]; then
            gh api \
              --method DELETE \
              &quot;repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}&quot;
          fi

      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment
      - name: rocket reaction
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7
        with:
          comment-id: ${{ needs.trigger.outputs.comment_id }}
          reactions: rocket

      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment
      - name: failure reaction
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7
        with:
          comment-id: ${{ needs.trigger.outputs.comment_id }}
          reactions: '-1'

      # if the deployment was successful, add a 'success' comment
      - name: success comment
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            ### Deployment Results ✅

            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**

      # if the deployment was not successful, add a 'failure' comment
      - name: failure comment
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            ### Deployment Results ❌

            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**"><pre><span class="pl-ent">name</span>: <span class="pl-s">deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">trigger</span>:
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }} </span><span class="pl-c"><span class="pl-c">#</span> only run on pull request comments</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">outputs</span>:
      <span class="pl-ent">continue</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue }}</span>
      <span class="pl-ent">noop</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.noop }}</span>
      <span class="pl-ent">deployment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.deployment_id }}</span>
      <span class="pl-ent">environment</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
      <span class="pl-ent">lock_ref_sha</span>: <span class="pl-s">${{ steps.capture-lock.outputs.sha }}</span>
      <span class="pl-ent">sha</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
      <span class="pl-ent">comment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.comment_id }}</span>
      <span class="pl-ent">initial_reaction_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.initial_reaction_id }}</span>
      <span class="pl-ent">actor_handle</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.actor_handle }}</span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">trigger</span>: <span class="pl-s"><span class="pl-pds">"</span>.deploy<span class="pl-pds">"</span></span>
          <span class="pl-ent">skip_completing</span>: <span class="pl-s">true </span><span class="pl-c"><span class="pl-c">#</span> we will complete the deployment manually</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">Capture deployment lock</span>
        <span class="pl-ent">id</span>: <span class="pl-s">capture-lock</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          if lock_ref_sha="$(gh api --method GET "repos/{owner}/{repo}/git/ref/heads/${lock_branch}" --jq '.object.sha' 2&gt;/dev/null)"; then</span>
<span class="pl-s">            printf 'sha=%s\n' "$lock_ref_sha" &gt;&gt; "$GITHUB_OUTPUT"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">trigger</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.trigger.outputs.continue == 'true' &amp;&amp; needs.trigger.outputs.noop != 'true' }}</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> checkout the project's repository based on the commit SHA provided by the branch-deploy step</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">checkout</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ needs.trigger.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

      <span class="pl-c"><span class="pl-c">#</span> You will do your own deployment here</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">fake regular deploy</span>
        <span class="pl-ent">run</span>: <span class="pl-s">echo "I am doing a fake regular deploy"</span>

  <span class="pl-c"><span class="pl-c">#</span> update the deployment result - manually complete the deployment that was created by the branch-deploy action</span>
  <span class="pl-ent">result</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">[trigger, deploy]</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-c"><span class="pl-c">#</span> run even on failures but only if the trigger job set continue to true</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ always() &amp;&amp; needs.trigger.outputs.continue == 'true' }}</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> if a previous step failed, set a variable to use as the deployment status</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">set deployment status</span>
        <span class="pl-ent">id</span>: <span class="pl-s">deploy-status</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.trigger.result == 'failure' || needs.deploy.result == 'failure' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          echo "DEPLOY_STATUS=failure" &gt;&gt; $GITHUB_OUTPUT</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Create a deployment status</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">DEPLOYMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.deployment_id }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">DEPLOY_STATUS</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS }}</span>
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.trigger.outputs.environment }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "${DEPLOY_STATUS}" ]; then</span>
<span class="pl-s">            DEPLOY_STATUS="success"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          gh api \</span>
<span class="pl-s">            --method POST \</span>
<span class="pl-s">            "repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses" \</span>
<span class="pl-s">            -f environment="${ENVIRONMENT}" \</span>
<span class="pl-s">            -f state="${DEPLOY_STATUS}"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Remove a non-sticky lock</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">COMMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.trigger.outputs.environment }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">ISSUE_NUMBER</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">LOCK_ACTOR</span>: <span class="pl-s">${{ github.actor }}</span>
          <span class="pl-ent">LOCK_REF_SHA</span>: <span class="pl-s">${{ needs.trigger.outputs.lock_ref_sha }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "${LOCK_REF_SHA}" ]; then</span>
<span class="pl-s">            echo "No captured deployment lock remains"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          lock_contents="$(gh api --method GET "repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}" --jq '.content' | base64 --decode)"</span>
<span class="pl-s">          lock_link="${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}"</span>
<span class="pl-s"></span>
<span class="pl-s">          if ! printf '%s' "$lock_contents" | jq -e \</span>
<span class="pl-s">            --arg actor "$LOCK_ACTOR" \</span>
<span class="pl-s">            --arg environment "$ENVIRONMENT" \</span>
<span class="pl-s">            --arg link "$lock_link" \</span>
<span class="pl-s">            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then</span>
<span class="pl-s">            echo "The captured deployment lock is sticky or belongs to another deployment"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          repository_id="$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')"</span>
<span class="pl-s">          if gh api graphql \</span>
<span class="pl-s">            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: "0000000000000000000000000000000000000000"}]}) { clientMutationId } }' \</span>
<span class="pl-s">            -f repository="$repository_id" \</span>
<span class="pl-s">            -f name="refs/heads/${lock_branch}" \</span>
<span class="pl-s">            -f before="$LOCK_REF_SHA" &gt;/dev/null; then</span>
<span class="pl-s">            echo "Removed the original deployment lock"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::The original deployment lock changed; leaving the current lock in place"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> remove the default 'eyes' reaction from the comment that triggered the deployment</span>
      <span class="pl-c"><span class="pl-c">#</span> this reaction is added by the branch-deploy action by default</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">remove eyes reaction</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">COMMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">INITIAL_REACTION_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.initial_reaction_id }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -n "${INITIAL_REACTION_ID}" ]; then</span>
<span class="pl-s">            gh api \</span>
<span class="pl-s">              --method DELETE \</span>
<span class="pl-s">              "repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">rocket reaction</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.0.7</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">comment-id</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">reactions</span>: <span class="pl-s">rocket</span>

      <span class="pl-c"><span class="pl-c">#</span> if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">failure reaction</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.0.7</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">comment-id</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">reactions</span>: <span class="pl-s"><span class="pl-pds">'</span>-1<span class="pl-pds">'</span></span>

      <span class="pl-c"><span class="pl-c">#</span> if the deployment was successful, add a 'success' comment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">success comment</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.1.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">body</span>: <span class="pl-s">|</span>
<span class="pl-s">            ### Deployment Results ✅</span>
<span class="pl-s"></span>
<span class="pl-s">            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> if the deployment was not successful, add a 'failure' comment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">failure comment</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.1.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">body</span>: <span class="pl-s">|</span>
<span class="pl-s">            ### Deployment Results ❌</span>
<span class="pl-s"></span>
<span class="pl-s">            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Multiple Jobs with GitHub Pages and Hugo</h2><a id="user-content-multiple-jobs-with-github-pages-and-hugo" class="anchor" aria-label="Permalink: Multiple Jobs with GitHub Pages and Hugo" href="#multiple-jobs-with-github-pages-and-hugo"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments. This example showcases building a static site with <a href="https://gohugo.io/" rel="nofollow">hugo</a> and deploying it to <a href="https://pages.github.com/">GitHub Pages</a>.</p>
<blockquote>
<p dir="auto">This live example can be found <a href="https://github.com/GrantBirki/blog/blob/559b9be5cc3eac923be5d7923ec9a0b50429ced2/.github/workflows/branch-deploy.yml">here</a></p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch deploy

# The workflow to execute on is comments that are newly created
on:
  issue_comment:
    types: [created]

# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read

# set an environment variable for use in the jobs pointing to my blog
env:
  blog_url: https://test.example.com # &lt;--- CHANGE THIS TO YOUR BLOG URL

jobs:
  # branch-deploy trigger job
  trigger:
    if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings
      ${{ github.event.issue.pull_request &amp;&amp;
      (contains(github.event.comment.body, '.deploy') ||
      contains(github.event.comment.body, '.lock') ||
      contains(github.event.comment.body, '.noop') ||
      contains(github.event.comment.body, '.help') ||
      contains(github.event.comment.body, '.wcid') ||
      contains(github.event.comment.body, '.unlock')) }}
    runs-on: ubuntu-latest
    outputs: # set outputs for use in downstream jobs
      continue: ${{ steps.branch-deploy.outputs.continue }}
      noop: ${{ steps.branch-deploy.outputs.noop }}
      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}
      environment: ${{ steps.branch-deploy.outputs.environment }}
      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}
      sha: ${{ steps.branch-deploy.outputs.sha }}
      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}
      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}
      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}

    steps:
      # execute the branch-deploy action
      - uses: github/branch-deploy@vX.X.X
        id: branch-deploy
        with:
          trigger: '.deploy'
          environment: 'github-pages'
          production_environments: 'github-pages'
          skip_completing: true # we will complete the deployment manually in the 'result' job
          admins: 'false' # &lt;--- add your GitHub username here (if you want to use the admins feature)

      - name: Capture deployment lock
        id: capture-lock
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
        run: |
          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          if lock_ref_sha=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}&quot; --jq '.object.sha' 2&gt;/dev/null)&quot;; then
            printf 'sha=%s\n' &quot;$lock_ref_sha&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
          else
            echo &quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped&quot;
          fi

  # build the github-pages site with hugo
  build:
    needs: trigger
    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
    runs-on: ubuntu-latest

    steps:
      # checkout the project's repository based on the commit SHA provided by the branch-deploy step
      - name: checkout
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ needs.trigger.outputs.sha }}
          persist-credentials: false

      # read the hugo version from the .hugo-version file in this repository
      - name: set hugo version
        id: hugo-version
        run: |
          HUGO_VERSION=$(cat .hugo-version)
          echo &quot;HUGO_VERSION=${HUGO_VERSION}&quot; &gt;&gt; $GITHUB_OUTPUT

      # install the hugo cli using the version detected in the previous step
      - name: install hugo cli
        env:
          HUGO_VERSION: ${{ steps.hugo-version.outputs.HUGO_VERSION }}
        run: |
          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.deb \
          &amp;&amp; sudo dpkg -i ${{ runner.temp }}/hugo.deb

      # configure the GitHub Pages action
      - name: setup pages
        id: pages
        uses: actions/configure-pages@c5a3e1159e0cbdf0845eb8811bd39e39fc3099c2 # pin@v2.1.3

      # build the site with hugo
      - name: build with hugo
        env:
          BASE_URL: ${{ steps.pages.outputs.base_url }}
        run: |
          hugo --gc --verbose \
            --baseURL &quot;$BASE_URL&quot;

      # this step is custom to my blog and adds a 'commit' version to the site
      - name: write build version
        run: echo ${GITHUB_SHA} &gt; ./public/version.txt

      # upload the built site as an artifact for the deploy step
      - name: upload artifact
        uses: actions/upload-pages-artifact@253fd476ed429e83b7aae64a92a75b4ceb1a17cf # pin@v1.0.7
        with:
          path: ./public

  # deploy to GitHub Pages
  deploy:
    needs: [trigger, build]
    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest

    steps:
      # deploy the site to GitHub Pages
      - name: deploy
        id: deployment
        uses: actions/deploy-pages@20a4baa1095bad40ba7d6ca0d9abbc220b76603f # pin@v1.2.3

  # update the deployment result - manually complete the deployment that was created by the branch-deploy action
  result:
    needs: [trigger, build, deploy]
    runs-on: ubuntu-latest
    # run even on failures but only if the trigger job set continue to true
    if: ${{ always() &amp;&amp; needs.trigger.outputs.continue == 'true' }}

    steps:
      # if a previous step failed, set a variable to use as the deployment status
      - name: set deployment status
        id: deploy-status
        if:
          ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||
          needs.deploy.result == 'failure' }}
        run: |
          echo &quot;DEPLOY_STATUS=failure&quot; &gt;&gt; $GITHUB_OUTPUT

      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action
      - name: Create a deployment status
        env:
          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}
          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}
        run: |
          if [ -z &quot;${DEPLOY_STATUS}&quot; ]; then
            DEPLOY_STATUS=&quot;success&quot;
          fi

          gh api \
            --method POST \
            &quot;repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses&quot; \
            -f environment=&quot;${ENVIRONMENT}&quot; \
            -f state=&quot;${DEPLOY_STATUS}&quot;

      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action
      - name: Remove a non-sticky lock
        env:
          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}
          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
          LOCK_ACTOR: ${{ github.actor }}
          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}
        run: |
          if [ -z &quot;${LOCK_REF_SHA}&quot; ]; then
            echo &quot;No captured deployment lock remains&quot;
            exit 0
          fi

          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          lock_contents=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}&quot; --jq '.content' | base64 --decode)&quot;
          lock_link=&quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}&quot;

          if ! printf '%s' &quot;$lock_contents&quot; | jq -e \
            --arg actor &quot;$LOCK_ACTOR&quot; \
            --arg environment &quot;$ENVIRONMENT&quot; \
            --arg link &quot;$lock_link&quot; \
            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then
            echo &quot;The captured deployment lock is sticky or belongs to another deployment&quot;
            exit 0
          fi

          repository_id=&quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')&quot;
          if gh api graphql \
            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: &quot;0000000000000000000000000000000000000000&quot;}]}) { clientMutationId } }' \
            -f repository=&quot;$repository_id&quot; \
            -f name=&quot;refs/heads/${lock_branch}&quot; \
            -f before=&quot;$LOCK_REF_SHA&quot; &gt;/dev/null; then
            echo &quot;Removed the original deployment lock&quot;
          else
            echo &quot;::warning::The original deployment lock changed; leaving the current lock in place&quot;
          fi

      # remove the default 'eyes' reaction from the comment that triggered the deployment
      # this reaction is added by the branch-deploy action by default
      - name: remove eyes reaction
        env:
          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}
        run: |
          if [ -n &quot;${INITIAL_REACTION_ID}&quot; ]; then
            gh api \
              --method DELETE \
              &quot;repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}&quot;
          fi

      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment
      - name: rocket reaction
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7
        with:
          comment-id: ${{ needs.trigger.outputs.comment_id }}
          reactions: rocket

      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment
      - name: failure reaction
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7
        with:
          comment-id: ${{ needs.trigger.outputs.comment_id }}
          reactions: '-1'

      # if the deployment was successful, add a 'success' comment
      - name: success comment
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            ### Deployment Results ✅

            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**

            &gt; [View Live Deployment](${{ env.blog_url }}) :link:

      # if the deployment was not successful, add a 'failure' comment
      - name: failure comment
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            ### Deployment Results ❌

            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch deploy</span>

<span class="pl-c"><span class="pl-c">#</span> The workflow to execute on is comments that are newly created</span>
<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-c"><span class="pl-c">#</span> Permissions needed for reacting and adding comments for IssueOps commands</span>
<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>

<span class="pl-c"><span class="pl-c">#</span> set an environment variable for use in the jobs pointing to my blog</span>
<span class="pl-ent">env</span>:
  <span class="pl-ent">blog_url</span>: <span class="pl-s">https://test.example.com </span><span class="pl-c"><span class="pl-c">#</span> &lt;--- CHANGE THIS TO YOUR BLOG URL</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-c"><span class="pl-c">#</span> branch-deploy trigger job</span>
  <span class="pl-ent">trigger</span>:
    <span class="pl-ent">if</span>: <span class="pl-c"><span class="pl-c">#</span> only run on pull request comments and very specific comment body string as defined in our branch-deploy settings</span>
      <span class="pl-s">${{ github.event.issue.pull_request &amp;&amp;</span>
      <span class="pl-s">(contains(github.event.comment.body, '.deploy') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.lock') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.noop') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.help') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.wcid') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.unlock')) }}</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">outputs</span>: <span class="pl-c"><span class="pl-c">#</span> set outputs for use in downstream jobs</span>
      <span class="pl-ent">continue</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue }}</span>
      <span class="pl-ent">noop</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.noop }}</span>
      <span class="pl-ent">deployment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.deployment_id }}</span>
      <span class="pl-ent">environment</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
      <span class="pl-ent">lock_ref_sha</span>: <span class="pl-s">${{ steps.capture-lock.outputs.sha }}</span>
      <span class="pl-ent">sha</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
      <span class="pl-ent">comment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.comment_id }}</span>
      <span class="pl-ent">initial_reaction_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.initial_reaction_id }}</span>
      <span class="pl-ent">actor_handle</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.actor_handle }}</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> execute the branch-deploy action</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">trigger</span>: <span class="pl-s"><span class="pl-pds">'</span>.deploy<span class="pl-pds">'</span></span>
          <span class="pl-ent">environment</span>: <span class="pl-s"><span class="pl-pds">'</span>github-pages<span class="pl-pds">'</span></span>
          <span class="pl-ent">production_environments</span>: <span class="pl-s"><span class="pl-pds">'</span>github-pages<span class="pl-pds">'</span></span>
          <span class="pl-ent">skip_completing</span>: <span class="pl-s">true </span><span class="pl-c"><span class="pl-c">#</span> we will complete the deployment manually in the 'result' job</span>
          <span class="pl-ent">admins</span>: <span class="pl-s"><span class="pl-pds">'</span>false<span class="pl-pds">'</span></span> <span class="pl-c"><span class="pl-c">#</span> &lt;--- add your GitHub username here (if you want to use the admins feature)</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">Capture deployment lock</span>
        <span class="pl-ent">id</span>: <span class="pl-s">capture-lock</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          if lock_ref_sha="$(gh api --method GET "repos/{owner}/{repo}/git/ref/heads/${lock_branch}" --jq '.object.sha' 2&gt;/dev/null)"; then</span>
<span class="pl-s">            printf 'sha=%s\n' "$lock_ref_sha" &gt;&gt; "$GITHUB_OUTPUT"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>  <span class="pl-c"><span class="pl-c">#</span> build the github-pages site with hugo</span>
  <span class="pl-ent">build</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">trigger</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.trigger.outputs.continue == 'true' }} </span><span class="pl-c"><span class="pl-c">#</span> only run if the trigger job set continue to true</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> checkout the project's repository based on the commit SHA provided by the branch-deploy step</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">checkout</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ needs.trigger.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

      <span class="pl-c"><span class="pl-c">#</span> read the hugo version from the .hugo-version file in this repository</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">set hugo version</span>
        <span class="pl-ent">id</span>: <span class="pl-s">hugo-version</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          HUGO_VERSION=$(cat .hugo-version)</span>
<span class="pl-s">          echo "HUGO_VERSION=${HUGO_VERSION}" &gt;&gt; $GITHUB_OUTPUT</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> install the hugo cli using the version detected in the previous step</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">install hugo cli</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">HUGO_VERSION</span>: <span class="pl-s">${{ steps.hugo-version.outputs.HUGO_VERSION }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.deb \</span>
<span class="pl-s">          &amp;&amp; sudo dpkg -i ${{ runner.temp }}/hugo.deb</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> configure the GitHub Pages action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">setup pages</span>
        <span class="pl-ent">id</span>: <span class="pl-s">pages</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/configure-pages@c5a3e1159e0cbdf0845eb8811bd39e39fc3099c2 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.1.3</span>

      <span class="pl-c"><span class="pl-c">#</span> build the site with hugo</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">build with hugo</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">BASE_URL</span>: <span class="pl-s">${{ steps.pages.outputs.base_url }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          hugo --gc --verbose \</span>
<span class="pl-s">            --baseURL "$BASE_URL"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> this step is custom to my blog and adds a 'commit' version to the site</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">write build version</span>
        <span class="pl-ent">run</span>: <span class="pl-s">echo ${GITHUB_SHA} &gt; ./public/version.txt</span>

      <span class="pl-c"><span class="pl-c">#</span> upload the built site as an artifact for the deploy step</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">upload artifact</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/upload-pages-artifact@253fd476ed429e83b7aae64a92a75b4ceb1a17cf </span><span class="pl-c"><span class="pl-c">#</span> pin@v1.0.7</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">path</span>: <span class="pl-s">./public</span>

  <span class="pl-c"><span class="pl-c">#</span> deploy to GitHub Pages</span>
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">[trigger, build]</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.trigger.outputs.continue == 'true' }} </span><span class="pl-c"><span class="pl-c">#</span> only run if the trigger job set continue to true</span>
    <span class="pl-ent">environment</span>:
      <span class="pl-ent">name</span>: <span class="pl-s">github-pages</span>
      <span class="pl-ent">url</span>: <span class="pl-s">${{ steps.deployment.outputs.page_url }}</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> deploy the site to GitHub Pages</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">deploy</span>
        <span class="pl-ent">id</span>: <span class="pl-s">deployment</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/deploy-pages@20a4baa1095bad40ba7d6ca0d9abbc220b76603f </span><span class="pl-c"><span class="pl-c">#</span> pin@v1.2.3</span>

  <span class="pl-c"><span class="pl-c">#</span> update the deployment result - manually complete the deployment that was created by the branch-deploy action</span>
  <span class="pl-ent">result</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">[trigger, build, deploy]</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-c"><span class="pl-c">#</span> run even on failures but only if the trigger job set continue to true</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ always() &amp;&amp; needs.trigger.outputs.continue == 'true' }}</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> if a previous step failed, set a variable to use as the deployment status</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">set deployment status</span>
        <span class="pl-ent">id</span>: <span class="pl-s">deploy-status</span>
        <span class="pl-ent">if</span>:
          <span class="pl-s">${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||</span>
          <span class="pl-s">needs.deploy.result == 'failure' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          echo "DEPLOY_STATUS=failure" &gt;&gt; $GITHUB_OUTPUT</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Create a deployment status</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">DEPLOYMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.deployment_id }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">DEPLOY_STATUS</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS }}</span>
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.trigger.outputs.environment }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "${DEPLOY_STATUS}" ]; then</span>
<span class="pl-s">            DEPLOY_STATUS="success"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          gh api \</span>
<span class="pl-s">            --method POST \</span>
<span class="pl-s">            "repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses" \</span>
<span class="pl-s">            -f environment="${ENVIRONMENT}" \</span>
<span class="pl-s">            -f state="${DEPLOY_STATUS}"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Remove a non-sticky lock</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">COMMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.trigger.outputs.environment }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">ISSUE_NUMBER</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">LOCK_ACTOR</span>: <span class="pl-s">${{ github.actor }}</span>
          <span class="pl-ent">LOCK_REF_SHA</span>: <span class="pl-s">${{ needs.trigger.outputs.lock_ref_sha }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "${LOCK_REF_SHA}" ]; then</span>
<span class="pl-s">            echo "No captured deployment lock remains"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          lock_contents="$(gh api --method GET "repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}" --jq '.content' | base64 --decode)"</span>
<span class="pl-s">          lock_link="${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}"</span>
<span class="pl-s"></span>
<span class="pl-s">          if ! printf '%s' "$lock_contents" | jq -e \</span>
<span class="pl-s">            --arg actor "$LOCK_ACTOR" \</span>
<span class="pl-s">            --arg environment "$ENVIRONMENT" \</span>
<span class="pl-s">            --arg link "$lock_link" \</span>
<span class="pl-s">            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then</span>
<span class="pl-s">            echo "The captured deployment lock is sticky or belongs to another deployment"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          repository_id="$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')"</span>
<span class="pl-s">          if gh api graphql \</span>
<span class="pl-s">            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: "0000000000000000000000000000000000000000"}]}) { clientMutationId } }' \</span>
<span class="pl-s">            -f repository="$repository_id" \</span>
<span class="pl-s">            -f name="refs/heads/${lock_branch}" \</span>
<span class="pl-s">            -f before="$LOCK_REF_SHA" &gt;/dev/null; then</span>
<span class="pl-s">            echo "Removed the original deployment lock"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::The original deployment lock changed; leaving the current lock in place"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> remove the default 'eyes' reaction from the comment that triggered the deployment</span>
      <span class="pl-c"><span class="pl-c">#</span> this reaction is added by the branch-deploy action by default</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">remove eyes reaction</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">COMMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">INITIAL_REACTION_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.initial_reaction_id }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -n "${INITIAL_REACTION_ID}" ]; then</span>
<span class="pl-s">            gh api \</span>
<span class="pl-s">              --method DELETE \</span>
<span class="pl-s">              "repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">rocket reaction</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.0.7</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">comment-id</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">reactions</span>: <span class="pl-s">rocket</span>

      <span class="pl-c"><span class="pl-c">#</span> if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">failure reaction</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.0.7</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">comment-id</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">reactions</span>: <span class="pl-s"><span class="pl-pds">'</span>-1<span class="pl-pds">'</span></span>

      <span class="pl-c"><span class="pl-c">#</span> if the deployment was successful, add a 'success' comment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">success comment</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.1.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">body</span>: <span class="pl-s">|</span>
<span class="pl-s">            ### Deployment Results ✅</span>
<span class="pl-s"></span>
<span class="pl-s">            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**</span>
<span class="pl-s"></span>
<span class="pl-s">            &gt; [View Live Deployment](${{ env.blog_url }}) :link:</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> if the deployment was not successful, add a 'failure' comment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">failure comment</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.1.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">body</span>: <span class="pl-s">|</span>
<span class="pl-s">            ### Deployment Results ❌</span>
<span class="pl-s"></span>
<span class="pl-s">            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Multiple Jobs with GitHub Pages and Astro</h2><a id="user-content-multiple-jobs-with-github-pages-and-astro" class="anchor" aria-label="Permalink: Multiple Jobs with GitHub Pages and Astro" href="#multiple-jobs-with-github-pages-and-astro"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments - Using <a href="https://astro.build" rel="nofollow">Astro</a> to create a static site and deploying to <a href="https://pages.github.com/">GitHub Pages</a></p>
<blockquote>
<p dir="auto">A live example can be found <a href="https://github.com/GrantBirki/astrowind-hard-fork/blob/be29d05cc0f3fe04e37ade9d38c653ed55c6cf53/.github/workflows/branch-deploy.yml">here</a></p>
</blockquote>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: branch deploy

# The workflow to execute on is comments that are newly created
on:
  issue_comment:
    types: [created]

# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
  pull-requests: write
  deployments: write
  contents: write
  checks: read
  statuses: read
  pages: write
  id-token: write

# set an environment variable for use in the jobs pointing the site_url
env:
  site_url: https://test.example.com # &lt;--- change this to your site url

jobs:
  # branch-deploy trigger job
  trigger:
    if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings
      ${{ github.event.issue.pull_request &amp;&amp;
      (contains(github.event.comment.body, '.deploy') ||
      contains(github.event.comment.body, '.lock') ||
      contains(github.event.comment.body, '.noop') ||
      contains(github.event.comment.body, '.help') ||
      contains(github.event.comment.body, '.wcid') ||
      contains(github.event.comment.body, '.unlock')) }}
    runs-on: ubuntu-latest
    outputs: # set outputs for use in downstream jobs
      continue: ${{ steps.branch-deploy.outputs.continue }}
      noop: ${{ steps.branch-deploy.outputs.noop }}
      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}
      environment: ${{ steps.branch-deploy.outputs.environment }}
      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}
      sha: ${{ steps.branch-deploy.outputs.sha }}
      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}
      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}
      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}

    steps:
      # execute the branch-deploy action
      - uses: github/branch-deploy@vX.X.X
        id: branch-deploy
        with:
          trigger: '.deploy'
          environment: 'github-pages'
          production_environments: 'github-pages'
          environment_targets: 'github-pages'
          skip_completing: true # we will complete the deployment manually in the 'result' job
          admins: 'false' # &lt;--- add your GitHub username here (if you want to use the admins feature)

      - name: Capture deployment lock
        id: capture-lock
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
        run: |
          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          if lock_ref_sha=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}&quot; --jq '.object.sha' 2&gt;/dev/null)&quot;; then
            printf 'sha=%s\n' &quot;$lock_ref_sha&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
          else
            echo &quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped&quot;
          fi

  # build the github-pages site with Astro
  build:
    needs: trigger
    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
    runs-on: ubuntu-latest

    steps:
      - name: checkout
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ needs.trigger.outputs.sha }}
          persist-credentials: false

      - name: build with astro
        uses: withastro/action@e3193ac80e18917ceaeb9f2d47019ad3b2c0416a # pin@v0.3.0

  # deploy to GitHub Pages
  deploy:
    needs: [trigger, build]
    if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest

    steps:
      # deploy the site to GitHub Pages
      - name: deploy
        id: deployment
        uses: actions/deploy-pages@497da40f5225e762159b457c9ae5d6f75a136f5c # pin@v1.2.5

  # update the deployment result - manually complete the deployment that was created by the branch-deploy action
  result:
    needs: [trigger, build, deploy]
    runs-on: ubuntu-latest
    # run even on failures but only if the trigger job set continue to true
    if: ${{ always() &amp;&amp; needs.trigger.outputs.continue == 'true' }}

    steps:
      # if a previous step failed, set a variable to use as the deployment status
      - name: set deployment status
        id: deploy-status
        if:
          ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||
          needs.deploy.result == 'failure' }}
        run: |
          echo &quot;DEPLOY_STATUS=failure&quot; &gt;&gt; $GITHUB_OUTPUT

      # use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action
      - name: Create a deployment status
        env:
          DEPLOYMENT_ID: ${{ needs.trigger.outputs.deployment_id }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}
          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}
        run: |
          if [ -z &quot;${DEPLOY_STATUS}&quot; ]; then
            DEPLOY_STATUS=&quot;success&quot;
          fi

          gh api \
            --method POST \
            &quot;repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses&quot; \
            -f environment=&quot;${ENVIRONMENT}&quot; \
            -f state=&quot;${DEPLOY_STATUS}&quot;

      # use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action
      - name: Remove a non-sticky lock
        env:
          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}
          ENVIRONMENT: ${{ needs.trigger.outputs.environment }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
          LOCK_ACTOR: ${{ github.actor }}
          LOCK_REF_SHA: ${{ needs.trigger.outputs.lock_ref_sha }}
        run: |
          if [ -z &quot;${LOCK_REF_SHA}&quot; ]; then
            echo &quot;No captured deployment lock remains&quot;
            exit 0
          fi

          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          lock_contents=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}&quot; --jq '.content' | base64 --decode)&quot;
          lock_link=&quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}&quot;

          if ! printf '%s' &quot;$lock_contents&quot; | jq -e \
            --arg actor &quot;$LOCK_ACTOR&quot; \
            --arg environment &quot;$ENVIRONMENT&quot; \
            --arg link &quot;$lock_link&quot; \
            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then
            echo &quot;The captured deployment lock is sticky or belongs to another deployment&quot;
            exit 0
          fi

          repository_id=&quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')&quot;
          if gh api graphql \
            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: &quot;0000000000000000000000000000000000000000&quot;}]}) { clientMutationId } }' \
            -f repository=&quot;$repository_id&quot; \
            -f name=&quot;refs/heads/${lock_branch}&quot; \
            -f before=&quot;$LOCK_REF_SHA&quot; &gt;/dev/null; then
            echo &quot;Removed the original deployment lock&quot;
          else
            echo &quot;::warning::The original deployment lock changed; leaving the current lock in place&quot;
          fi

      # remove the default 'eyes' reaction from the comment that triggered the deployment
      # this reaction is added by the branch-deploy action by default
      - name: remove eyes reaction
        env:
          COMMENT_ID: ${{ needs.trigger.outputs.comment_id }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
          INITIAL_REACTION_ID: ${{ needs.trigger.outputs.initial_reaction_id }}
        run: |
          if [ -n &quot;${INITIAL_REACTION_ID}&quot; ]; then
            gh api \
              --method DELETE \
              &quot;repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}&quot;
          fi

      # if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment
      - name: rocket reaction
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7
        with:
          comment-id: ${{ needs.trigger.outputs.comment_id }}
          reactions: rocket

      # if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment
      - name: failure reaction
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7
        with:
          comment-id: ${{ needs.trigger.outputs.comment_id }}
          reactions: '-1'

      # if the deployment was successful, add a 'success' comment
      - name: success comment
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            ### Deployment Results ✅

            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**

            &gt; [View Live Deployment](${{ env.site_url }}) :link:

      # if the deployment was not successful, add a 'failure' comment
      - name: failure comment
        if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
        uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # pin@v2.1.1
        with:
          issue-number: ${{ github.event.issue.number }}
          body: |
            ### Deployment Results ❌

            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**"><pre><span class="pl-ent">name</span>: <span class="pl-s">branch deploy</span>

<span class="pl-c"><span class="pl-c">#</span> The workflow to execute on is comments that are newly created</span>
<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>: <span class="pl-s">[created]</span>

<span class="pl-c"><span class="pl-c">#</span> Permissions needed for reacting and adding comments for IssueOps commands</span>
<span class="pl-ent">permissions</span>:
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>
  <span class="pl-ent">pages</span>: <span class="pl-s">write</span>
  <span class="pl-ent">id-token</span>: <span class="pl-s">write</span>

<span class="pl-c"><span class="pl-c">#</span> set an environment variable for use in the jobs pointing the site_url</span>
<span class="pl-ent">env</span>:
  <span class="pl-ent">site_url</span>: <span class="pl-s">https://test.example.com </span><span class="pl-c"><span class="pl-c">#</span> &lt;--- change this to your site url</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-c"><span class="pl-c">#</span> branch-deploy trigger job</span>
  <span class="pl-ent">trigger</span>:
    <span class="pl-ent">if</span>: <span class="pl-c"><span class="pl-c">#</span> only run on pull request comments and very specific comment body string as defined in our branch-deploy settings</span>
      <span class="pl-s">${{ github.event.issue.pull_request &amp;&amp;</span>
      <span class="pl-s">(contains(github.event.comment.body, '.deploy') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.lock') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.noop') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.help') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.wcid') ||</span>
      <span class="pl-s">contains(github.event.comment.body, '.unlock')) }}</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-ent">outputs</span>: <span class="pl-c"><span class="pl-c">#</span> set outputs for use in downstream jobs</span>
      <span class="pl-ent">continue</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue }}</span>
      <span class="pl-ent">noop</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.noop }}</span>
      <span class="pl-ent">deployment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.deployment_id }}</span>
      <span class="pl-ent">environment</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
      <span class="pl-ent">lock_ref_sha</span>: <span class="pl-s">${{ steps.capture-lock.outputs.sha }}</span>
      <span class="pl-ent">sha</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
      <span class="pl-ent">comment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.comment_id }}</span>
      <span class="pl-ent">initial_reaction_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.initial_reaction_id }}</span>
      <span class="pl-ent">actor_handle</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.actor_handle }}</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> execute the branch-deploy action</span>
      - <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">trigger</span>: <span class="pl-s"><span class="pl-pds">'</span>.deploy<span class="pl-pds">'</span></span>
          <span class="pl-ent">environment</span>: <span class="pl-s"><span class="pl-pds">'</span>github-pages<span class="pl-pds">'</span></span>
          <span class="pl-ent">production_environments</span>: <span class="pl-s"><span class="pl-pds">'</span>github-pages<span class="pl-pds">'</span></span>
          <span class="pl-ent">environment_targets</span>: <span class="pl-s"><span class="pl-pds">'</span>github-pages<span class="pl-pds">'</span></span>
          <span class="pl-ent">skip_completing</span>: <span class="pl-s">true </span><span class="pl-c"><span class="pl-c">#</span> we will complete the deployment manually in the 'result' job</span>
          <span class="pl-ent">admins</span>: <span class="pl-s"><span class="pl-pds">'</span>false<span class="pl-pds">'</span></span> <span class="pl-c"><span class="pl-c">#</span> &lt;--- add your GitHub username here (if you want to use the admins feature)</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">Capture deployment lock</span>
        <span class="pl-ent">id</span>: <span class="pl-s">capture-lock</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          if lock_ref_sha="$(gh api --method GET "repos/{owner}/{repo}/git/ref/heads/${lock_branch}" --jq '.object.sha' 2&gt;/dev/null)"; then</span>
<span class="pl-s">            printf 'sha=%s\n' "$lock_ref_sha" &gt;&gt; "$GITHUB_OUTPUT"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>  <span class="pl-c"><span class="pl-c">#</span> build the github-pages site with Astro</span>
  <span class="pl-ent">build</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">trigger</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.trigger.outputs.continue == 'true' }} </span><span class="pl-c"><span class="pl-c">#</span> only run if the trigger job set continue to true</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">checkout</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ needs.trigger.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">build with astro</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">withastro/action@e3193ac80e18917ceaeb9f2d47019ad3b2c0416a </span><span class="pl-c"><span class="pl-c">#</span> pin@v0.3.0</span>

  <span class="pl-c"><span class="pl-c">#</span> deploy to GitHub Pages</span>
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">[trigger, build]</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.trigger.outputs.continue == 'true' }} </span><span class="pl-c"><span class="pl-c">#</span> only run if the trigger job set continue to true</span>
    <span class="pl-ent">environment</span>:
      <span class="pl-ent">name</span>: <span class="pl-s">github-pages</span>
      <span class="pl-ent">url</span>: <span class="pl-s">${{ steps.deployment.outputs.page_url }}</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> deploy the site to GitHub Pages</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">deploy</span>
        <span class="pl-ent">id</span>: <span class="pl-s">deployment</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/deploy-pages@497da40f5225e762159b457c9ae5d6f75a136f5c </span><span class="pl-c"><span class="pl-c">#</span> pin@v1.2.5</span>

  <span class="pl-c"><span class="pl-c">#</span> update the deployment result - manually complete the deployment that was created by the branch-deploy action</span>
  <span class="pl-ent">result</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">[trigger, build, deploy]</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>
    <span class="pl-c"><span class="pl-c">#</span> run even on failures but only if the trigger job set continue to true</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ always() &amp;&amp; needs.trigger.outputs.continue == 'true' }}</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> if a previous step failed, set a variable to use as the deployment status</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">set deployment status</span>
        <span class="pl-ent">id</span>: <span class="pl-s">deploy-status</span>
        <span class="pl-ent">if</span>:
          <span class="pl-s">${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||</span>
          <span class="pl-s">needs.deploy.result == 'failure' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          echo "DEPLOY_STATUS=failure" &gt;&gt; $GITHUB_OUTPUT</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Create a deployment status</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">DEPLOYMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.deployment_id }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">DEPLOY_STATUS</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS }}</span>
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.trigger.outputs.environment }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "${DEPLOY_STATUS}" ]; then</span>
<span class="pl-s">            DEPLOY_STATUS="success"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          gh api \</span>
<span class="pl-s">            --method POST \</span>
<span class="pl-s">            "repos/{owner}/{repo}/deployments/${DEPLOYMENT_ID}/statuses" \</span>
<span class="pl-s">            -f environment="${ENVIRONMENT}" \</span>
<span class="pl-s">            -f state="${DEPLOY_STATUS}"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Remove a non-sticky lock</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">COMMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.trigger.outputs.environment }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">ISSUE_NUMBER</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">LOCK_ACTOR</span>: <span class="pl-s">${{ github.actor }}</span>
          <span class="pl-ent">LOCK_REF_SHA</span>: <span class="pl-s">${{ needs.trigger.outputs.lock_ref_sha }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "${LOCK_REF_SHA}" ]; then</span>
<span class="pl-s">            echo "No captured deployment lock remains"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          lock_contents="$(gh api --method GET "repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}" --jq '.content' | base64 --decode)"</span>
<span class="pl-s">          lock_link="${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}"</span>
<span class="pl-s"></span>
<span class="pl-s">          if ! printf '%s' "$lock_contents" | jq -e \</span>
<span class="pl-s">            --arg actor "$LOCK_ACTOR" \</span>
<span class="pl-s">            --arg environment "$ENVIRONMENT" \</span>
<span class="pl-s">            --arg link "$lock_link" \</span>
<span class="pl-s">            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then</span>
<span class="pl-s">            echo "The captured deployment lock is sticky or belongs to another deployment"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          repository_id="$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')"</span>
<span class="pl-s">          if gh api graphql \</span>
<span class="pl-s">            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: "0000000000000000000000000000000000000000"}]}) { clientMutationId } }' \</span>
<span class="pl-s">            -f repository="$repository_id" \</span>
<span class="pl-s">            -f name="refs/heads/${lock_branch}" \</span>
<span class="pl-s">            -f before="$LOCK_REF_SHA" &gt;/dev/null; then</span>
<span class="pl-s">            echo "Removed the original deployment lock"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::The original deployment lock changed; leaving the current lock in place"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> remove the default 'eyes' reaction from the comment that triggered the deployment</span>
      <span class="pl-c"><span class="pl-c">#</span> this reaction is added by the branch-deploy action by default</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">remove eyes reaction</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">COMMENT_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
          <span class="pl-ent">INITIAL_REACTION_ID</span>: <span class="pl-s">${{ needs.trigger.outputs.initial_reaction_id }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -n "${INITIAL_REACTION_ID}" ]; then</span>
<span class="pl-s">            gh api \</span>
<span class="pl-s">              --method DELETE \</span>
<span class="pl-s">              "repos/{owner}/{repo}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">rocket reaction</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.0.7</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">comment-id</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">reactions</span>: <span class="pl-s">rocket</span>

      <span class="pl-c"><span class="pl-c">#</span> if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">failure reaction</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.0.7</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">comment-id</span>: <span class="pl-s">${{ needs.trigger.outputs.comment_id }}</span>
          <span class="pl-ent">reactions</span>: <span class="pl-s"><span class="pl-pds">'</span>-1<span class="pl-pds">'</span></span>

      <span class="pl-c"><span class="pl-c">#</span> if the deployment was successful, add a 'success' comment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">success comment</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.1.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">body</span>: <span class="pl-s">|</span>
<span class="pl-s">            ### Deployment Results ✅</span>
<span class="pl-s"></span>
<span class="pl-s">            **${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**</span>
<span class="pl-s"></span>
<span class="pl-s">            &gt; [View Live Deployment](${{ env.site_url }}) :link:</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> if the deployment was not successful, add a 'failure' comment</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">failure comment</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.1.1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">issue-number</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
          <span class="pl-ent">body</span>: <span class="pl-s">|</span>
<span class="pl-s">            ### Deployment Results ❌</span>
<span class="pl-s"></span>
<span class="pl-s">            **${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Multiple Jobs with GitHub Environments</h2><a id="user-content-multiple-jobs-with-github-environments" class="anchor" aria-label="Permalink: Multiple Jobs with GitHub Environments" href="#multiple-jobs-with-github-environments"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A detailed example using multiple jobs, <a href="https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment">repository environments</a>, and Terraform. As mentioned in the <a href="https://github.com/github/branch-deploy#about-environments-">README</a>, a deployment completes when the workflow targeting that environment completes. In this example, the branch deployment action targets a separate environment than the "actual" deployment logic, which lets us control the completion of the branch deployment while being able to manage environments separately.</p>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="name: Branch Deploy

on:
  issue_comment:
    types:
      - created

env:
  # These variables are scoped to the **repository**.
  TF_VAR_image_repository: ${{ vars.IMAGE_REPOSITORY }}

permissions:
  checks: read
  statuses: read
  contents: write
  deployments: write
  packages: read
  pull-requests: write

jobs:
  start:
    name: Start Branch Deployment
    runs-on: ubuntu-latest

    # Only start branch deployments on pull request comments.
    if: ${{ github.event.issue.pull_request }}

    # The deployments environment is used by the branch-deploy workflow.
    environment: deployments

    # Set the outputs to be used by the rest of the workflow.
    outputs:
      continue: ${{ steps.branch-deploy.outputs.continue }}
      noop: ${{ steps.branch-deploy.outputs.noop }}
      deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}
      environment: ${{ steps.branch-deploy.outputs.environment }}
      lock_ref_sha: ${{ steps.capture-lock.outputs.sha }}
      sha: ${{ steps.branch-deploy.outputs.sha }}
      comment_id: ${{ steps.branch-deploy.outputs.comment_id }}
      initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}
      actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}

    steps:
      - name: Start Branch Deployment
        id: branch-deploy
        uses: github/branch-deploy@vX.X.X
        with:
          environment: development
          environment_targets: development,staging,production
          skip_completing: true

      - name: Capture deployment lock
        id: capture-lock
        if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
        env:
          ENVIRONMENT: ${{ steps.branch-deploy.outputs.environment }}
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
        run: |
          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          if lock_ref_sha=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/git/ref/heads/${lock_branch}&quot; --jq '.object.sha' 2&gt;/dev/null)&quot;; then
            printf 'sha=%s\n' &quot;$lock_ref_sha&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
          else
            echo &quot;::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped&quot;
          fi

  # This is the &quot;actual&quot; deployment logic. It uses the environment specified in
  # the branch deployment comment (e.g. `.deploy to development`).
  deploy:
    needs: start

    name: Deploy
    runs-on: ubuntu-latest

    # Only start after the branch deployment has initialized.
    if: ${{ needs.start.outputs.continue == 'true' }}

    # Use the environment specified by the `.noop` or `.deploy` comment.
    environment: ${{ needs.start.outputs.environment }}

    # Set the default working directory to `tf/` (or wherever your Terraform
    # code is located in your repository).
    defaults:
      run:
        working-directory: tf/

    # Set the deployment outcome based on if `terraform plan` (.noop) or
    # `terraform apply` (.deploy) succeeded. Defaults to 'failure'.
    outputs:
      outcome: ${{ (steps.plan.outcome == 'success' || steps.apply.outcome == 'success') &amp;&amp; 'success' || 'failure' }}

    # These variables/secrets are scoped to the **environment**.
    env:
      ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
      ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
      ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
      TF_VAR_location: ${{ vars.AZURE_LOCATION }}

    steps:
      - name: Checkout
        id: checkout
        uses: actions/checkout@v7.0.0
        with:
          ref: ${{ needs.start.outputs.sha }}
          persist-credentials: false

      # Authenticate to Azure using OpenID Connect.
      - name: Authenticate to Azure (OIDC)
        id: azure-oidc
        uses: azure/login@v1
        with:
          client-id: ${{ env.ARM_CLIENT_ID }}
          subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}
          tenant-id: ${{ env.ARM_TENANT_ID }}

      # Install Terraform on the runner.
      - name: Setup Terraform
        id: setup-terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.5

      # This example uses separate Terraform workspaces for each environment.
      - name: Terraform Init
        id: terraform-init
        env:
          ENVIRONMENT: ${{ needs.start.outputs.environment }}
        run: |
          terraform init -no-color
          terraform workspace select -or-create=true &quot;$ENVIRONMENT&quot;

      # If this is a `.noop`, run `terraform plan` to see what would change.
      - name: Terraform Plan
        id: plan
        if: ${{ needs.start.outputs.noop == 'true' }}
        run: terraform plan -no-color
        continue-on-error: true

      # If this is a `.deploy`, run `terraform apply` to apply the changes.
      - name: Terraform Apply
        id: apply
        if: ${{ needs.start.outputs.noop != 'true' }}
        run: terraform apply -no-color -auto-approve
        continue-on-error: true

      # Get the output from the plan/apply step.
      - name: Save Terraform Output
        id: output
        env:
          PLAN_STDOUT: ${{ steps.plan.outputs.stdout }}
          APPLY_STDOUT: ${{ steps.apply.outputs.stdout }}
        run: |
          if [ -z &quot;$PLAN_STDOUT&quot; ]
          then
            echo &quot;$APPLY_STDOUT&quot; &gt; tf_output.txt
          else
            echo &quot;$PLAN_STDOUT&quot; &gt; tf_output.txt
          fi

      # Upload the plan/apply output as an artifact so that it can be used in
      # the `stop` job.
      - name: Upload Terraform Output
        id: upload
        uses: actions/upload-artifact@v3
        with:
          name: tf_output
          path: tf/tf_output.txt

  stop:
    needs:
      - start
      - deploy

    name: Stop Branch Deployment
    runs-on: ubuntu-latest

    # Always run this job if the branch deployment was started.
    if: ${{ always() &amp;&amp; needs.start.outputs.continue == 'true' }}

    # Switch back to the deployments environment to update the branch
    # deployment status.
    environment: deployments

    # Get the outputs from the `start` job. These are needed to finish the
    # branch deployment, comment on the PR, update reactions, etc.
    env:
      ACTOR: ${{ needs.start.outputs.actor_handle }}
      COMMENT_ID: ${{ needs.start.outputs.comment_id }}
      DEPLOYMENT_ID: ${{ needs.start.outputs.deployment_id }}
      DEPLOYMENT_STATUS: ${{ needs.deploy.outputs.outcome || 'failure' }}
      ENVIRONMENT: ${{ needs.start.outputs.environment }}
      GH_REPO: ${{ github.repository }}
      GH_TOKEN: ${{ github.token }}
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      INITIAL_REACTION_ID: ${{ needs.start.outputs.initial_reaction_id }}
      ISSUE_NUMBER: ${{ github.event.issue.number }}
      LOCK_ACTOR: ${{ github.actor }}
      LOCK_REF_SHA: ${{ needs.start.outputs.lock_ref_sha }}
      NOOP: ${{ needs.start.outputs.noop }}
      SHA: ${{ needs.start.outputs.sha }}
      REPOSITORY: ${{ github.repository }}

    steps:
      # Tf this was not a `.noop` deployment, set the status.
      - if: ${{ env.NOOP != 'true' }}
        name: Set Deployment Status
        id: set-status
        run: |
          gh api --method POST \
            &quot;repos/${REPOSITORY}/deployments/${DEPLOYMENT_ID}/statuses&quot; \
            -f environment=&quot;${ENVIRONMENT}&quot; \
            -f state=&quot;${DEPLOYMENT_STATUS}&quot;

      # Remove the non-sticky lock for either a `.noop` or `.deploy`.
      - name: Remove Non-Sticky Lock
        id: remove-lock
        run: |
          if [ -z &quot;${LOCK_REF_SHA}&quot; ]; then
            echo &quot;No captured deployment lock remains&quot;
            exit 0
          fi

          lock_branch=&quot;$(printf '%s' &quot;$ENVIRONMENT&quot; | jq -Rsr 'gsub(&quot;\\s&quot;; &quot;-&quot;)')-branch-deploy-lock&quot;
          lock_contents=&quot;$(gh api --method GET &quot;repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}&quot; --jq '.content' | base64 --decode)&quot;
          lock_link=&quot;${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}&quot;

          if ! printf '%s' &quot;$lock_contents&quot; | jq -e \
            --arg actor &quot;$LOCK_ACTOR&quot; \
            --arg environment &quot;$ENVIRONMENT&quot; \
            --arg link &quot;$lock_link&quot; \
            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then
            echo &quot;The captured deployment lock is sticky or belongs to another deployment&quot;
            exit 0
          fi

          repository_id=&quot;$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')&quot;
          if gh api graphql \
            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: &quot;0000000000000000000000000000000000000000&quot;}]}) { clientMutationId } }' \
            -f repository=&quot;$repository_id&quot; \
            -f name=&quot;refs/heads/${lock_branch}&quot; \
            -f before=&quot;$LOCK_REF_SHA&quot; &gt;/dev/null; then
            echo &quot;Removed the original deployment lock&quot;
          else
            echo &quot;::warning::The original deployment lock changed; leaving the current lock in place&quot;
          fi

      # Remove the trigger reaction added to the user's comment.
      - name: Remove Trigger Reaction
        id: remove-reaction
        run: |
          if [ -n &quot;${INITIAL_REACTION_ID}&quot; ]; then
            gh api --method DELETE \
              &quot;repos/${REPOSITORY}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}&quot;
          fi

      # Add a new reaction based on if the deployment succeeded or failed.
      - name: Add Reaction
        id: add-reaction
        uses: GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 # pin@v2.0.7
        env:
          REACTION: ${{ env.DEPLOYMENT_STATUS == 'success' &amp;&amp; 'rocket' || '-1' }}
        with:
          comment-id: ${{ env.COMMENT_ID }}
          reactions: ${{ env.DEPLOYMENT_STATUS == 'success' &amp;&amp; 'rocket' || '-1' }}

      # If the plan/apply didn't run because of a failure, this step will also
      # fail, hence setting continue-on-error.
      - name: Get Terraform Output Artifact
        id: get-artifact
        uses: actions/download-artifact@v3
        with:
          name: tf_output
        continue-on-error: true

      # Add a success comment, including the plan/apply output (if present).
      - if: ${{ env.DEPLOYMENT_STATUS == 'success' }}
        name: Add Success Comment
        id: success-comment
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs')

            let output
            try { output = fs.readFileSync('tf_output.txt', 'utf8') }
            catch (err) { output = 'No Terraform output!' }

            await github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `### Deployment Results :white_check_mark:

            **${process.env.ACTOR}** successfully ${ process.env.NOOP === 'true' ? '**noop** deployed' : 'deployed' } sha \`${process.env.SHA}\` to **${process.env.ENVIRONMENT}**

            &lt;details&gt;&lt;summary&gt;Show Results&lt;/summary&gt;

            \`\`\`terraform\n${ output }\n\`\`\`

            &lt;/details&gt;`
            })

      # Add a failure comment, including the plan/apply output (if present).
      - if: ${{ env.DEPLOYMENT_STATUS == 'failure' }}
        name: Add Failure Comment
        id: failure-comment
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs')

            let output
            try { output = fs.readFileSync('tf_output.txt', 'utf8') }
            catch (err) { output = 'No Terraform output!' }

            await github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `### Deployment Results :x:

            **${process.env.ACTOR}** had a failure when ${ process.env.NOOP === 'true' ? '**noop** deploying' : 'deploying' } sha \`${process.env.SHA}\` to **${process.env.ENVIRONMENT}**

            &lt;details&gt;&lt;summary&gt;Show Results&lt;/summary&gt;

            \`\`\`terraform\n${ output }\n\`\`\`

            &lt;/details&gt;`
            })

      # If the deployment failed, fail the workflow.
      - if: ${{ env.DEPLOYMENT_STATUS == 'failure' }}
        name: Fail Workflow
        id: fail-workflow
        run: |
          echo &quot;There was a deployment problem...failing the workflow!&quot;
          exit 1"><pre><span class="pl-ent">name</span>: <span class="pl-s">Branch Deploy</span>

<span class="pl-ent">on</span>:
  <span class="pl-ent">issue_comment</span>:
    <span class="pl-ent">types</span>:
      - <span class="pl-s">created</span>

<span class="pl-ent">env</span>:
  <span class="pl-c"><span class="pl-c">#</span> These variables are scoped to the **repository**.</span>
  <span class="pl-ent">TF_VAR_image_repository</span>: <span class="pl-s">${{ vars.IMAGE_REPOSITORY }}</span>

<span class="pl-ent">permissions</span>:
  <span class="pl-ent">checks</span>: <span class="pl-s">read</span>
  <span class="pl-ent">statuses</span>: <span class="pl-s">read</span>
  <span class="pl-ent">contents</span>: <span class="pl-s">write</span>
  <span class="pl-ent">deployments</span>: <span class="pl-s">write</span>
  <span class="pl-ent">packages</span>: <span class="pl-s">read</span>
  <span class="pl-ent">pull-requests</span>: <span class="pl-s">write</span>

<span class="pl-ent">jobs</span>:
  <span class="pl-ent">start</span>:
    <span class="pl-ent">name</span>: <span class="pl-s">Start Branch Deployment</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-c"><span class="pl-c">#</span> Only start branch deployments on pull request comments.</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ github.event.issue.pull_request }}</span>

    <span class="pl-c"><span class="pl-c">#</span> The deployments environment is used by the branch-deploy workflow.</span>
    <span class="pl-ent">environment</span>: <span class="pl-s">deployments</span>

    <span class="pl-c"><span class="pl-c">#</span> Set the outputs to be used by the rest of the workflow.</span>
    <span class="pl-ent">outputs</span>:
      <span class="pl-ent">continue</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue }}</span>
      <span class="pl-ent">noop</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.noop }}</span>
      <span class="pl-ent">deployment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.deployment_id }}</span>
      <span class="pl-ent">environment</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
      <span class="pl-ent">lock_ref_sha</span>: <span class="pl-s">${{ steps.capture-lock.outputs.sha }}</span>
      <span class="pl-ent">sha</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.sha }}</span>
      <span class="pl-ent">comment_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.comment_id }}</span>
      <span class="pl-ent">initial_reaction_id</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.initial_reaction_id }}</span>
      <span class="pl-ent">actor_handle</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.actor_handle }}</span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">Start Branch Deployment</span>
        <span class="pl-ent">id</span>: <span class="pl-s">branch-deploy</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">github/branch-deploy@vX.X.X</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">environment</span>: <span class="pl-s">development</span>
          <span class="pl-ent">environment_targets</span>: <span class="pl-s">development,staging,production</span>
          <span class="pl-ent">skip_completing</span>: <span class="pl-c1">true</span>

      - <span class="pl-ent">name</span>: <span class="pl-s">Capture deployment lock</span>
        <span class="pl-ent">id</span>: <span class="pl-s">capture-lock</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.continue == 'true' }}</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ steps.branch-deploy.outputs.environment }}</span>
          <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
          <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          if lock_ref_sha="$(gh api --method GET "repos/{owner}/{repo}/git/ref/heads/${lock_branch}" --jq '.object.sha' 2&gt;/dev/null)"; then</span>
<span class="pl-s">            printf 'sha=%s\n' "$lock_ref_sha" &gt;&gt; "$GITHUB_OUTPUT"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::Could not capture the original deployment lock; manual lock cleanup will be skipped"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>  <span class="pl-c"><span class="pl-c">#</span> This is the "actual" deployment logic. It uses the environment specified in</span>
  <span class="pl-c"><span class="pl-c">#</span> the branch deployment comment (e.g. `.deploy to development`).</span>
  <span class="pl-ent">deploy</span>:
    <span class="pl-ent">needs</span>: <span class="pl-s">start</span>

    <span class="pl-ent">name</span>: <span class="pl-s">Deploy</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-c"><span class="pl-c">#</span> Only start after the branch deployment has initialized.</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.start.outputs.continue == 'true' }}</span>

    <span class="pl-c"><span class="pl-c">#</span> Use the environment specified by the `.noop` or `.deploy` comment.</span>
    <span class="pl-ent">environment</span>: <span class="pl-s">${{ needs.start.outputs.environment }}</span>

    <span class="pl-c"><span class="pl-c">#</span> Set the default working directory to `tf/` (or wherever your Terraform</span>
    <span class="pl-c"><span class="pl-c">#</span> code is located in your repository).</span>
    <span class="pl-ent">defaults</span>:
      <span class="pl-ent">run</span>:
        <span class="pl-ent">working-directory</span>: <span class="pl-s">tf/</span>

    <span class="pl-c"><span class="pl-c">#</span> Set the deployment outcome based on if `terraform plan` (.noop) or</span>
    <span class="pl-c"><span class="pl-c">#</span> `terraform apply` (.deploy) succeeded. Defaults to 'failure'.</span>
    <span class="pl-ent">outputs</span>:
      <span class="pl-ent">outcome</span>: <span class="pl-s">${{ (steps.plan.outcome == 'success' || steps.apply.outcome == 'success') &amp;&amp; 'success' || 'failure' }}</span>

    <span class="pl-c"><span class="pl-c">#</span> These variables/secrets are scoped to the **environment**.</span>
    <span class="pl-ent">env</span>:
      <span class="pl-ent">ARM_CLIENT_ID</span>: <span class="pl-s">${{ secrets.ARM_CLIENT_ID }}</span>
      <span class="pl-ent">ARM_SUBSCRIPTION_ID</span>: <span class="pl-s">${{ secrets.ARM_SUBSCRIPTION_ID }}</span>
      <span class="pl-ent">ARM_TENANT_ID</span>: <span class="pl-s">${{ secrets.ARM_TENANT_ID }}</span>
      <span class="pl-ent">TF_VAR_location</span>: <span class="pl-s">${{ vars.AZURE_LOCATION }}</span>

    <span class="pl-ent">steps</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">Checkout</span>
        <span class="pl-ent">id</span>: <span class="pl-s">checkout</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/checkout@v7.0.0</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">ref</span>: <span class="pl-s">${{ needs.start.outputs.sha }}</span>
          <span class="pl-ent">persist-credentials</span>: <span class="pl-c1">false</span>

      <span class="pl-c"><span class="pl-c">#</span> Authenticate to Azure using OpenID Connect.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Authenticate to Azure (OIDC)</span>
        <span class="pl-ent">id</span>: <span class="pl-s">azure-oidc</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">azure/login@v1</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">client-id</span>: <span class="pl-s">${{ env.ARM_CLIENT_ID }}</span>
          <span class="pl-ent">subscription-id</span>: <span class="pl-s">${{ env.ARM_SUBSCRIPTION_ID }}</span>
          <span class="pl-ent">tenant-id</span>: <span class="pl-s">${{ env.ARM_TENANT_ID }}</span>

      <span class="pl-c"><span class="pl-c">#</span> Install Terraform on the runner.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Setup Terraform</span>
        <span class="pl-ent">id</span>: <span class="pl-s">setup-terraform</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">hashicorp/setup-terraform@v2</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">terraform_version</span>: <span class="pl-s">1.5.5</span>

      <span class="pl-c"><span class="pl-c">#</span> This example uses separate Terraform workspaces for each environment.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Terraform Init</span>
        <span class="pl-ent">id</span>: <span class="pl-s">terraform-init</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.start.outputs.environment }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          terraform init -no-color</span>
<span class="pl-s">          terraform workspace select -or-create=true "$ENVIRONMENT"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> If this is a `.noop`, run `terraform plan` to see what would change.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Terraform Plan</span>
        <span class="pl-ent">id</span>: <span class="pl-s">plan</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.start.outputs.noop == 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform plan -no-color</span>
        <span class="pl-ent">continue-on-error</span>: <span class="pl-c1">true</span>

      <span class="pl-c"><span class="pl-c">#</span> If this is a `.deploy`, run `terraform apply` to apply the changes.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Terraform Apply</span>
        <span class="pl-ent">id</span>: <span class="pl-s">apply</span>
        <span class="pl-ent">if</span>: <span class="pl-s">${{ needs.start.outputs.noop != 'true' }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">terraform apply -no-color -auto-approve</span>
        <span class="pl-ent">continue-on-error</span>: <span class="pl-c1">true</span>

      <span class="pl-c"><span class="pl-c">#</span> Get the output from the plan/apply step.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Save Terraform Output</span>
        <span class="pl-ent">id</span>: <span class="pl-s">output</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">PLAN_STDOUT</span>: <span class="pl-s">${{ steps.plan.outputs.stdout }}</span>
          <span class="pl-ent">APPLY_STDOUT</span>: <span class="pl-s">${{ steps.apply.outputs.stdout }}</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "$PLAN_STDOUT" ]</span>
<span class="pl-s">          then</span>
<span class="pl-s">            echo "$APPLY_STDOUT" &gt; tf_output.txt</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "$PLAN_STDOUT" &gt; tf_output.txt</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> Upload the plan/apply output as an artifact so that it can be used in</span>
      <span class="pl-c"><span class="pl-c">#</span> the `stop` job.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Upload Terraform Output</span>
        <span class="pl-ent">id</span>: <span class="pl-s">upload</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/upload-artifact@v3</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">name</span>: <span class="pl-s">tf_output</span>
          <span class="pl-ent">path</span>: <span class="pl-s">tf/tf_output.txt</span>

  <span class="pl-ent">stop</span>:
    <span class="pl-ent">needs</span>:
      - <span class="pl-s">start</span>
      - <span class="pl-s">deploy</span>

    <span class="pl-ent">name</span>: <span class="pl-s">Stop Branch Deployment</span>
    <span class="pl-ent">runs-on</span>: <span class="pl-s">ubuntu-latest</span>

    <span class="pl-c"><span class="pl-c">#</span> Always run this job if the branch deployment was started.</span>
    <span class="pl-ent">if</span>: <span class="pl-s">${{ always() &amp;&amp; needs.start.outputs.continue == 'true' }}</span>

    <span class="pl-c"><span class="pl-c">#</span> Switch back to the deployments environment to update the branch</span>
    <span class="pl-c"><span class="pl-c">#</span> deployment status.</span>
    <span class="pl-ent">environment</span>: <span class="pl-s">deployments</span>

    <span class="pl-c"><span class="pl-c">#</span> Get the outputs from the `start` job. These are needed to finish the</span>
    <span class="pl-c"><span class="pl-c">#</span> branch deployment, comment on the PR, update reactions, etc.</span>
    <span class="pl-ent">env</span>:
      <span class="pl-ent">ACTOR</span>: <span class="pl-s">${{ needs.start.outputs.actor_handle }}</span>
      <span class="pl-ent">COMMENT_ID</span>: <span class="pl-s">${{ needs.start.outputs.comment_id }}</span>
      <span class="pl-ent">DEPLOYMENT_ID</span>: <span class="pl-s">${{ needs.start.outputs.deployment_id }}</span>
      <span class="pl-ent">DEPLOYMENT_STATUS</span>: <span class="pl-s">${{ needs.deploy.outputs.outcome || 'failure' }}</span>
      <span class="pl-ent">ENVIRONMENT</span>: <span class="pl-s">${{ needs.start.outputs.environment }}</span>
      <span class="pl-ent">GH_REPO</span>: <span class="pl-s">${{ github.repository }}</span>
      <span class="pl-ent">GH_TOKEN</span>: <span class="pl-s">${{ github.token }}</span>
      <span class="pl-ent">GITHUB_TOKEN</span>: <span class="pl-s">${{ secrets.GITHUB_TOKEN }}</span>
      <span class="pl-ent">INITIAL_REACTION_ID</span>: <span class="pl-s">${{ needs.start.outputs.initial_reaction_id }}</span>
      <span class="pl-ent">ISSUE_NUMBER</span>: <span class="pl-s">${{ github.event.issue.number }}</span>
      <span class="pl-ent">LOCK_ACTOR</span>: <span class="pl-s">${{ github.actor }}</span>
      <span class="pl-ent">LOCK_REF_SHA</span>: <span class="pl-s">${{ needs.start.outputs.lock_ref_sha }}</span>
      <span class="pl-ent">NOOP</span>: <span class="pl-s">${{ needs.start.outputs.noop }}</span>
      <span class="pl-ent">SHA</span>: <span class="pl-s">${{ needs.start.outputs.sha }}</span>
      <span class="pl-ent">REPOSITORY</span>: <span class="pl-s">${{ github.repository }}</span>

    <span class="pl-ent">steps</span>:
      <span class="pl-c"><span class="pl-c">#</span> Tf this was not a `.noop` deployment, set the status.</span>
      - <span class="pl-ent">if</span>: <span class="pl-s">${{ env.NOOP != 'true' }}</span>
        <span class="pl-ent">name</span>: <span class="pl-s">Set Deployment Status</span>
        <span class="pl-ent">id</span>: <span class="pl-s">set-status</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          gh api --method POST \</span>
<span class="pl-s">            "repos/${REPOSITORY}/deployments/${DEPLOYMENT_ID}/statuses" \</span>
<span class="pl-s">            -f environment="${ENVIRONMENT}" \</span>
<span class="pl-s">            -f state="${DEPLOYMENT_STATUS}"</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> Remove the non-sticky lock for either a `.noop` or `.deploy`.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Remove Non-Sticky Lock</span>
        <span class="pl-ent">id</span>: <span class="pl-s">remove-lock</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -z "${LOCK_REF_SHA}" ]; then</span>
<span class="pl-s">            echo "No captured deployment lock remains"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          lock_branch="$(printf '%s' "$ENVIRONMENT" | jq -Rsr 'gsub("\\s"; "-")')-branch-deploy-lock"</span>
<span class="pl-s">          lock_contents="$(gh api --method GET "repos/{owner}/{repo}/contents/lock.json?ref=${LOCK_REF_SHA}" --jq '.content' | base64 --decode)"</span>
<span class="pl-s">          lock_link="${GITHUB_SERVER_URL}/${GH_REPO}/pull/${ISSUE_NUMBER}#issuecomment-${COMMENT_ID}"</span>
<span class="pl-s"></span>
<span class="pl-s">          if ! printf '%s' "$lock_contents" | jq -e \</span>
<span class="pl-s">            --arg actor "$LOCK_ACTOR" \</span>
<span class="pl-s">            --arg environment "$ENVIRONMENT" \</span>
<span class="pl-s">            --arg link "$lock_link" \</span>
<span class="pl-s">            '.created_by == $actor and .environment == $environment and .global == false and .sticky == false and .link == $link' &gt;/dev/null; then</span>
<span class="pl-s">            echo "The captured deployment lock is sticky or belongs to another deployment"</span>
<span class="pl-s">            exit 0</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s">          repository_id="$(gh api --method GET 'repos/{owner}/{repo}' --jq '.node_id')"</span>
<span class="pl-s">          if gh api graphql \</span>
<span class="pl-s">            -f query='mutation($repository: ID!, $name: GitRefname!, $before: GitObjectID!) { updateRefs(input: {repositoryId: $repository, refUpdates: [{name: $name, beforeOid: $before, afterOid: "0000000000000000000000000000000000000000"}]}) { clientMutationId } }' \</span>
<span class="pl-s">            -f repository="$repository_id" \</span>
<span class="pl-s">            -f name="refs/heads/${lock_branch}" \</span>
<span class="pl-s">            -f before="$LOCK_REF_SHA" &gt;/dev/null; then</span>
<span class="pl-s">            echo "Removed the original deployment lock"</span>
<span class="pl-s">          else</span>
<span class="pl-s">            echo "::warning::The original deployment lock changed; leaving the current lock in place"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> Remove the trigger reaction added to the user's comment.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Remove Trigger Reaction</span>
        <span class="pl-ent">id</span>: <span class="pl-s">remove-reaction</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          if [ -n "${INITIAL_REACTION_ID}" ]; then</span>
<span class="pl-s">            gh api --method DELETE \</span>
<span class="pl-s">              "repos/${REPOSITORY}/issues/comments/${COMMENT_ID}/reactions/${INITIAL_REACTION_ID}"</span>
<span class="pl-s">          fi</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> Add a new reaction based on if the deployment succeeded or failed.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Add Reaction</span>
        <span class="pl-ent">id</span>: <span class="pl-s">add-reaction</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">GrantBirki/comment@e6bf4bc177996c9572b4ddb98b25eb1a80f9abc9 </span><span class="pl-c"><span class="pl-c">#</span> pin@v2.0.7</span>
        <span class="pl-ent">env</span>:
          <span class="pl-ent">REACTION</span>: <span class="pl-s">${{ env.DEPLOYMENT_STATUS == 'success' &amp;&amp; 'rocket' || '-1' }}</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">comment-id</span>: <span class="pl-s">${{ env.COMMENT_ID }}</span>
          <span class="pl-ent">reactions</span>: <span class="pl-s">${{ env.DEPLOYMENT_STATUS == 'success' &amp;&amp; 'rocket' || '-1' }}</span>

      <span class="pl-c"><span class="pl-c">#</span> If the plan/apply didn't run because of a failure, this step will also</span>
      <span class="pl-c"><span class="pl-c">#</span> fail, hence setting continue-on-error.</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Get Terraform Output Artifact</span>
        <span class="pl-ent">id</span>: <span class="pl-s">get-artifact</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/download-artifact@v3</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">name</span>: <span class="pl-s">tf_output</span>
        <span class="pl-ent">continue-on-error</span>: <span class="pl-c1">true</span>

      <span class="pl-c"><span class="pl-c">#</span> Add a success comment, including the plan/apply output (if present).</span>
      - <span class="pl-ent">if</span>: <span class="pl-s">${{ env.DEPLOYMENT_STATUS == 'success' }}</span>
        <span class="pl-ent">name</span>: <span class="pl-s">Add Success Comment</span>
        <span class="pl-ent">id</span>: <span class="pl-s">success-comment</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/github-script@v6</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">script</span>: <span class="pl-s">|</span>
<span class="pl-s">            const fs = require('fs')</span>
<span class="pl-s"></span>
<span class="pl-s">            let output</span>
<span class="pl-s">            try { output = fs.readFileSync('tf_output.txt', 'utf8') }</span>
<span class="pl-s">            catch (err) { output = 'No Terraform output!' }</span>
<span class="pl-s"></span>
<span class="pl-s">            await github.rest.issues.createComment({</span>
<span class="pl-s">              issue_number: context.issue.number,</span>
<span class="pl-s">              owner: context.repo.owner,</span>
<span class="pl-s">              repo: context.repo.repo,</span>
<span class="pl-s">              body: `### Deployment Results :white_check_mark:</span>
<span class="pl-s"></span>
<span class="pl-s">            **${process.env.ACTOR}** successfully ${ process.env.NOOP === 'true' ? '**noop** deployed' : 'deployed' } sha \`${process.env.SHA}\` to **${process.env.ENVIRONMENT}**</span>
<span class="pl-s"></span>
<span class="pl-s">            &lt;details&gt;&lt;summary&gt;Show Results&lt;/summary&gt;</span>
<span class="pl-s"></span>
<span class="pl-s">            \`\`\`terraform\n${ output }\n\`\`\`</span>
<span class="pl-s"></span>
<span class="pl-s">            &lt;/details&gt;`</span>
<span class="pl-s">            })</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> Add a failure comment, including the plan/apply output (if present).</span>
      - <span class="pl-ent">if</span>: <span class="pl-s">${{ env.DEPLOYMENT_STATUS == 'failure' }}</span>
        <span class="pl-ent">name</span>: <span class="pl-s">Add Failure Comment</span>
        <span class="pl-ent">id</span>: <span class="pl-s">failure-comment</span>
        <span class="pl-ent">uses</span>: <span class="pl-s">actions/github-script@v6</span>
        <span class="pl-ent">with</span>:
          <span class="pl-ent">script</span>: <span class="pl-s">|</span>
<span class="pl-s">            const fs = require('fs')</span>
<span class="pl-s"></span>
<span class="pl-s">            let output</span>
<span class="pl-s">            try { output = fs.readFileSync('tf_output.txt', 'utf8') }</span>
<span class="pl-s">            catch (err) { output = 'No Terraform output!' }</span>
<span class="pl-s"></span>
<span class="pl-s">            await github.rest.issues.createComment({</span>
<span class="pl-s">              issue_number: context.issue.number,</span>
<span class="pl-s">              owner: context.repo.owner,</span>
<span class="pl-s">              repo: context.repo.repo,</span>
<span class="pl-s">              body: `### Deployment Results :x:</span>
<span class="pl-s"></span>
<span class="pl-s">            **${process.env.ACTOR}** had a failure when ${ process.env.NOOP === 'true' ? '**noop** deploying' : 'deploying' } sha \`${process.env.SHA}\` to **${process.env.ENVIRONMENT}**</span>
<span class="pl-s"></span>
<span class="pl-s">            &lt;details&gt;&lt;summary&gt;Show Results&lt;/summary&gt;</span>
<span class="pl-s"></span>
<span class="pl-s">            \`\`\`terraform\n${ output }\n\`\`\`</span>
<span class="pl-s"></span>
<span class="pl-s">            &lt;/details&gt;`</span>
<span class="pl-s">            })</span>
<span class="pl-s"></span>
<span class="pl-s"></span>      <span class="pl-c"><span class="pl-c">#</span> If the deployment failed, fail the workflow.</span>
      - <span class="pl-ent">if</span>: <span class="pl-s">${{ env.DEPLOYMENT_STATUS == 'failure' }}</span>
        <span class="pl-ent">name</span>: <span class="pl-s">Fail Workflow</span>
        <span class="pl-ent">id</span>: <span class="pl-s">fail-workflow</span>
        <span class="pl-ent">run</span>: <span class="pl-s">|</span>
<span class="pl-s">          echo "There was a deployment problem...failing the workflow!"</span>
<span class="pl-s">          exit 1</span></pre></div>
<hr>
<p dir="auto">Are you using the <code>branch-deploy</code> Action and want your example included here? Open a pull request and we'll add it!</p>
</article></div><div class="d-none"></div></section></div></div></div> </div> <!-- --> </div></div></div></div></div></div><div class="ScrollMarksContainer-module__scrollMarksContainer__Eu7uU" id="find-result-marks-container"></div><div class="d-none"></div><div class="d-none"></div></div> <!-- --> <!-- --> </div>
</react-app>




  </div>

</turbo-frame>

    </main>
  </div>

  </div>

          <footer class="footer f6 color-fg-muted color-border-subtle tmp-pt-7 tmp-pb-6 p-responsive" role="contentinfo"  >
  <h2 class='sr-only'>Footer</h2>

  


  <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap">
    <div class="d-flex flex-items-center flex-shrink-0 mx-2">
      <a aria-label="GitHub Homepage" class="footer-octicon mr-2" href="https://github.com">
        <svg aria-hidden="true" data-component="Octicon" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github">
    <path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
      <span>
        &copy; 2026 GitHub,&nbsp;Inc.
      </span>
    </div>

    <nav aria-label="Footer">
      <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3>

      <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading">


          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a>
          </li>


            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a>
            </li>

            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a>
            </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to community&quot;,&quot;label&quot;:&quot;text:community&quot;}" href="https://github.community/" data-view-component="true" class="Link--secondary Link">Community</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a>
          </li>

          
<li class="mx-2" >
  <cookie-consent-link>
    <button
      type="button"
      class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
      data-action="click:cookie-consent-link#showConsentManagement"
      data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
    >
      Manage cookies
    </button>
  </cookie-consent-link>
</li>

  <li class="mx-2">
    <cookie-consent-link>
      <button
        type="button"
        class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
        data-action="click:cookie-consent-link#showConsentManagement"
        data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
      >
        Do not share my personal information
      </button>
    </cookie-consent-link>
  </li>

      </ul>
    </nav>
  </div>
</footer>



    <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
      data-locale="en"
      data-initial-cookie-consent-allowed=""
      data-cookie-consent-required="true"
    ></ghcc-consent>




  <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden>
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    You can’t perform that action at this time.
  </div>

    <template id="site-details-dialog">
  <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open>
    <summary role="button" aria-label="Close dialog"></summary>
    <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
      <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
      </button>
      <div class="octocat-spinner tmp-my-6 js-details-dialog-spinner"></div>
    </details-dialog>
  </details>
</template>

    <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;">
  <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;">
  </div>
</div>

    <template id="snippet-clipboard-copy-button">
  <div class="zeroclipboard-container position-absolute right-0 top-0">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2 tmp-m-2">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2 tmp-m-2">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
  <div class="zeroclipboard-container">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>




    </div>
    <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
    <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
  </body>
</html>

