Skip to content

Commit

Permalink
adds github release filter and builds workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Jan 5, 2024
1 parent 9fdea28 commit 0bde563
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 2 deletions.
90 changes: 90 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Release

on:
push:
branches: [ "main" ]
tags: 'v*'
paths-ignore:
- 'doc/**'
- '.github/**'
workflow_dispatch:


jobs:
build_test_and_bundle:
strategy:
matrix:
os: [ubuntu-latest, ubuntu-20.04, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3

- name: setup rust stable
run: curl https://sh.rustup.rs -sSf | sh -s -- -y

- name: unit tests
run: cargo test --all --release

- name: bundle
shell: bash
run: |
mkdir Pulse
cp target/release/pulse Pulse/pulse-${{ matrix.os }}
cp LICENSE Pulse/
- name: upload bundle
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.os }}
path: Pulse

release:
needs: [build_test_and_bundle]
if: github.ref_type == 'tag'
runs-on: ubuntu-22.04

steps:

- name: get linux build
uses: actions/download-artifact@v3
with:
name: ubuntu-latest

- name: get windows build
uses: actions/download-artifact@v3
with:
name: windows-latest

- name: get macos build
uses: actions/download-artifact@v3
with:
name: macos-latest

- name: pack
run: |
mkdir linux windows macos
ls
mv pulse-ubuntu-latest pulse
chmod +x pulse
tar cvpfz linux-x86_64.tar.gz pulse LICENSE
mv pulse-windows-latest.exe pulse.exe
chmod +x pulse.exe
zip windows.zip pulse.exe LICENSE
mv pulse-macos-latest pulse
chmod +x pulse
tar cvpfz macOS.tar.gz pulse LICENSE
# https://github.com/softprops/action-gh-release
- name: release
uses: softprops/action-gh-release@v1
with:
draft: true
prerelease: true
name: "release-${{ github.ref_name }}"
tag_name: ${{ github.ref }}
files: |
linux-x86_64.tar.gz
windows.zip
macOS.tar.gz
103 changes: 103 additions & 0 deletions src/web/response/github_release.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//! Github release response
use std::collections::HashMap;

use axum::extract::State;
use axum::http::StatusCode;
use axum::response::IntoResponse;

use axum::response::Response;

use std::convert::{From, Into};

use chrono::Local;
use regex::Regex;

fn strip_control_characters(s: String) -> String
{
let re = Regex::new(r"[\u0000-\u001F]").unwrap().replace_all(&s, "");
return re.to_string()
}

#[derive(Debug)]
enum GITHUB_RELEASE_ACTION_TYPE
{
CREATED,
DELETED,
EDITED,
PRERELEASED,
PUBLISHED,
RELEASED,
UNPUBLISHED,
UNKOWN
}

impl From<&str> for GITHUB_RELEASE_ACTION_TYPE
{
fn from(s: &str) -> GITHUB_RELEASE_ACTION_TYPE
{
match s
{
"created" => Self::CREATED,
"deleted" => Self::DELETED,
"edited" => Self::EDITED,
"prereleased" => Self::PRERELEASED,
"published" => Self::PUBLISHED,
"released" => Self::RELEASED,
"unpublished" => Self::UNPUBLISHED,
_ => Self::UNKOWN
}
}
}

pub async fn github_release<B>
(
State(body): State<String>
) -> Result<Response, StatusCode>
{

let parsed_data: HashMap<String, serde_json::Value> = match serde_json::from_str(&strip_control_characters(body))
{
Ok(d) => d,
Err(e) =>
{
crate::debug(format!("error parsing body: {}", e), None);
return Ok((StatusCode::INTERNAL_SERVER_ERROR).into_response());
}
};

if parsed_data.contains_key("action")
{
let action: GITHUB_RELEASE_ACTION_TYPE = match parsed_data["action"].to_owned().as_str()
{
Some(s) => {s.into()},
None =>
{
crate::debug(format!("action could not be parsed \n\nGot:\n {:?}", parsed_data["action"]), None);
return Ok((StatusCode::BAD_REQUEST).into_response());
}
};

return respond(action, parsed_data).await;
}
else
{
crate::debug(format!("no action entry in JSON payload \n\nGot:\n {:?}", parsed_data), None);
return Ok((StatusCode::BAD_REQUEST).into_response());
}

}

async fn respond(action: GITHUB_RELEASE_ACTION_TYPE, data: HashMap<String, serde_json::Value>) -> Result<Response, StatusCode>
{
crate::debug(format!("Processing github release payload: {:?}", action), None);

match action
{
GITHUB_RELEASE_ACTION_TYPE::CREATED => {}
GITHUB_RELEASE_ACTION_TYPE::PUBLISHED => {},
_ => {}
}

Ok((StatusCode::OK).into_response())
}
39 changes: 38 additions & 1 deletion src/web/response/github_verify.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Utility responses for the axum server
//! Github POST verification
use axum::extract::State;
use axum::http::{StatusCode, HeaderMap};
Expand Down Expand Up @@ -41,6 +41,43 @@ pub fn read_bytes(v: String) -> Vec<u8>
.collect()
}

/// Middleware to detect and verify a github POST request form a
/// Github webhook
///
/// The github user agent header must be of the form GitHub-Hookshot/xxx
///
/// The hmac provided by the hmac x-hub-signature-256, is checked against
/// the State(app_state) value and the bodies bytes
///
/// The body is only read after the user agent matches
///
/// # Example
///
/// ```rust
/// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
/// use std::sync::{Arc, Mutex};
///
/// use axum::
/// {
/// routing::post,
/// Router,
/// middleware
/// };
///
/// let authenticated_state = "this_is_a_secret".to_string();
///
/// let app = Router::new()
/// .route("/", post(|| async move { }))
/// .layer(middleware::from_fn_with_state(authenticated_state.clone(), github_verify))
///
/// let ip = Ipv4Addr::new(127,0,0,1);
/// let addr = SocketAddr::new(IpAddr::V4(ip), port);
///
/// axum::Server::bind(&addr)
/// .serve(app.into_make_service_with_connect_info::<SocketAddr>())
/// .await
/// .unwrap();
/// ````
pub async fn github_verify<B>
(
State(app_state): State<String>,
Expand Down
3 changes: 2 additions & 1 deletion src/web/response/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod util;
pub mod github_verify;
pub mod github_verify;
pub mod github_release;

0 comments on commit 0bde563

Please sign in to comment.