diff --git a/.github/workflows/deploy-image.yml b/.github/workflows/deploy-image.yml index 7c4b74f3..c224a5e1 100644 --- a/.github/workflows/deploy-image.yml +++ b/.github/workflows/deploy-image.yml @@ -37,6 +37,10 @@ jobs: tags: | type=semver,pattern={{version}} type=edge,branch=main + - name: Set short sha + shell: bash + run: | + echo "sha_short=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV" - name: Build and push Docker image uses: docker/build-push-action@v4 @@ -47,3 +51,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} cache-from: type=gha cache-to: type=gha,mode=max + build-args: JF_GIT_COMMIT=${{ env.sha_short }} diff --git a/Dockerfile b/Dockerfile index c86006a6..969d8363 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,6 +51,9 @@ RUN mix release FROM alpine:3.17 AS app +ARG JF_GIT_COMMIT +ENV JF_GIT_COMMIT=$JF_GIT_COMMIT + RUN addgroup -S jellyfish && adduser -S jellyfish -G jellyfish # We run the whole image as root, fix permissions in diff --git a/config/runtime.exs b/config/runtime.exs index 6044a8a6..804b59fb 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -34,7 +34,8 @@ config :jellyfish, metrics_port: ConfigReader.read_port("JF_METRICS_PORT") || 9568, dist_config: ConfigReader.read_dist_config(), webrtc_config: ConfigReader.read_webrtc_config(), - sip_config: ConfigReader.read_sip_config() + sip_config: ConfigReader.read_sip_config(), + git_commit: ConfigReader.read_git_commit() case System.get_env("JF_SERVER_API_TOKEN") do nil when prod? == true -> diff --git a/lib/jellyfish.ex b/lib/jellyfish.ex index 341ef641..52a1505a 100644 --- a/lib/jellyfish.ex +++ b/lib/jellyfish.ex @@ -6,4 +6,8 @@ defmodule Jellyfish do Contexts are also responsible for managing your data, regardless if it comes from the database, an external API or others. """ + + @version Mix.Project.config()[:version] + + def version(), do: @version end diff --git a/lib/jellyfish/application.ex b/lib/jellyfish/application.ex index 596c31cb..c55fc00d 100644 --- a/lib/jellyfish/application.ex +++ b/lib/jellyfish/application.ex @@ -7,15 +7,14 @@ defmodule Jellyfish.Application do require Logger - @version Mix.Project.config()[:version] - @impl true def start(_type, _args) do scrape_interval = Application.fetch_env!(:jellyfish, :webrtc_metrics_scrape_interval) dist_config = Application.fetch_env!(:jellyfish, :dist_config) webrtc_config = Application.fetch_env!(:jellyfish, :webrtc_config) + git_commit = Application.get_env(:jellyfish, :git_commit) - Logger.info("Starting Jellyfish v#{@version}") + Logger.info("Starting Jellyfish v#{Jellyfish.version()} (#{git_commit})") Logger.info("Distribution config: #{inspect(Keyword.delete(dist_config, :cookie))}") Logger.info("WebRTC config: #{inspect(webrtc_config)}") diff --git a/lib/jellyfish/config_reader.ex b/lib/jellyfish/config_reader.ex index 245dfeaf..7b69cc96 100644 --- a/lib/jellyfish/config_reader.ex +++ b/lib/jellyfish/config_reader.ex @@ -180,6 +180,10 @@ defmodule Jellyfish.ConfigReader do end end + def read_git_commit() do + System.get_env("JF_GIT_COMMIT", "dev") + end + defp do_read_nodes_list_config(node_name_value, cookie, mode) do nodes_value = System.get_env("JF_DIST_NODES", "") @@ -300,7 +304,7 @@ defmodule Jellyfish.ConfigReader do {:error, reason} -> raise """ - Couldn't resolve #{hostname}, reason: #{reason}. + Couldn't resolve #{hostname}, reason: #{reason}. """ end end diff --git a/lib/jellyfish_web/api_spec.ex b/lib/jellyfish_web/api_spec.ex index 7a7186fe..194925b2 100644 --- a/lib/jellyfish_web/api_spec.ex +++ b/lib/jellyfish_web/api_spec.ex @@ -4,8 +4,6 @@ defmodule JellyfishWeb.ApiSpec do alias OpenApiSpex.{Components, Info, License, Paths, Schema, SecurityScheme} - @version Mix.Project.config()[:version] - # OpenAPISpex master specification @impl OpenApiSpex.OpenApi @@ -13,7 +11,7 @@ defmodule JellyfishWeb.ApiSpec do %OpenApiSpex.OpenApi{ info: %Info{ title: "Jellyfish Media Server", - version: @version, + version: Jellyfish.version(), license: %License{ name: "Apache 2.0", url: "https://www.apache.org/licenses/LICENSE-2.0" diff --git a/lib/jellyfish_web/api_spec/health_report.ex b/lib/jellyfish_web/api_spec/health_report.ex index c4aeea72..682c12dd 100644 --- a/lib/jellyfish_web/api_spec/health_report.ex +++ b/lib/jellyfish_web/api_spec/health_report.ex @@ -50,8 +50,10 @@ defmodule JellyfishWeb.ApiSpec.HealthReport do properties: %{ status: Status, uptime: %Schema{type: :integer, description: "Uptime of Jellyfish (in seconds)"}, - distribution: Distribution + distribution: Distribution, + version: %Schema{type: :string, description: "Version of Jellyfish"}, + gitCommit: %Schema{type: :string, description: "Commit hash of the build"} }, - required: [:status, :uptime, :distribution] + required: [:status, :uptime, :distribution, :version, :gitCommit] }) end diff --git a/lib/jellyfish_web/controllers/healthcheck_controller.ex b/lib/jellyfish_web/controllers/healthcheck_controller.ex index c5407ebc..de2ab21b 100644 --- a/lib/jellyfish_web/controllers/healthcheck_controller.ex +++ b/lib/jellyfish_web/controllers/healthcheck_controller.ex @@ -30,7 +30,9 @@ defmodule JellyfishWeb.HealthcheckController do %{ status: :up, uptime: get_uptime(), - distribution: get_distribution_report() + distribution: get_distribution_report(), + version: Jellyfish.version(), + gitCommit: Application.get_env(:jellyfish, :git_commit) } end diff --git a/lib/jellyfish_web/controllers/healthcheck_json.ex b/lib/jellyfish_web/controllers/healthcheck_json.ex index 46620075..22d2dc31 100644 --- a/lib/jellyfish_web/controllers/healthcheck_json.ex +++ b/lib/jellyfish_web/controllers/healthcheck_json.ex @@ -5,16 +5,17 @@ defmodule JellyfishWeb.HealthcheckJSON do %{data: data(report)} end - def data(%{status: status, uptime: uptime, distribution: distribution}) do - %{ + def data(%{status: status, distribution: distribution} = report) do + report + |> Map.take([:uptime, :version, :gitCommit]) + |> Map.merge(%{ status: status_str(status), - uptime: uptime, distribution: %{ enabled: distribution.enabled, nodeStatus: status_str(distribution.node_status), nodesInCluster: distribution.nodes_in_cluster } - } + }) end defp status_str(:up), do: "UP" diff --git a/mix.exs b/mix.exs index eb807cf2..10e2deaa 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Jellyfish.MixProject do def project do [ app: :jellyfish, - version: "0.4.1", + version: "0.4.2", elixir: "~> 1.14", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, diff --git a/openapi.yaml b/openapi.yaml index 88c5c724..0e9ec4d2 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -535,15 +535,23 @@ components: properties: distribution: $ref: '#/components/schemas/HealthReportDistribution' + gitCommit: + description: Commit hash of the build + type: string status: $ref: '#/components/schemas/HealthReportStatus' uptime: description: Uptime of Jellyfish (in seconds) type: integer + version: + description: Version of Jellyfish + type: string required: - status - uptime - distribution + - version + - gitCommit title: HealthReport type: object x-struct: Elixir.JellyfishWeb.ApiSpec.HealthReport @@ -747,7 +755,7 @@ info: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 title: Jellyfish Media Server - version: 0.4.1 + version: 0.4.2 openapi: 3.0.0 paths: /health: diff --git a/test/jellyfish_web/controllers/healthcheck_controller_test.exs b/test/jellyfish_web/controllers/healthcheck_controller_test.exs index 31d3b8f2..8ab06b8f 100644 --- a/test/jellyfish_web/controllers/healthcheck_controller_test.exs +++ b/test/jellyfish_web/controllers/healthcheck_controller_test.exs @@ -5,6 +5,8 @@ defmodule JellyfishWeb.HealthcheckControllerTest do @schema JellyfishWeb.ApiSpec.spec() + @commit_hash_length 7 + setup %{conn: conn} do server_api_token = Application.fetch_env!(:jellyfish, :server_api_token) conn = put_req_header(conn, "authorization", "Bearer " <> server_api_token) @@ -17,6 +19,8 @@ defmodule JellyfishWeb.HealthcheckControllerTest do response = json_response(conn, :ok) assert_response_schema(response, "HealthcheckResponse", @schema) + version = Jellyfish.version() + assert %{ "status" => "UP", "uptime" => _uptime, @@ -24,7 +28,11 @@ defmodule JellyfishWeb.HealthcheckControllerTest do "enabled" => false, "nodeStatus" => "DOWN", "nodesInCluster" => 0 - } + }, + "version" => ^version, + "gitCommit" => commit } = response["data"] + + assert commit == "dev" || String.length(commit) == @commit_hash_length end end